Krita Source Code Documentation
Loading...
Searching...
No Matches
KisLevelsConfigWidget Class Reference

#include <KisLevelsConfigWidget.h>

+ Inheritance diagram for KisLevelsConfigWidget:

Public Member Functions

KisPropertiesConfigurationSP configuration () const override
 
 KisLevelsConfigWidget (QWidget *parent, KisPaintDeviceSP dev, const KoColorSpace *colorSpace)
 
void setConfiguration (const KisPropertiesConfigurationSP config) override
 
 ~KisLevelsConfigWidget () override
 
- Public Member Functions inherited from KisConfigWidget
virtual KoCanvasResourcesInterfaceSP canvasResourcesInterface () const
 
virtual void setCanvasResourcesInterface (KoCanvasResourcesInterfaceSP canvasResourcesInterface)
 
virtual void setView (KisViewManager *view)
 
 ~KisConfigWidget () override
 

Private Slots

void computeChannelsMinMaxRanges ()
 
void resetAll ()
 
void resetAllChannels ()
 
void resetInputLevels ()
 
void resetOutputLevels ()
 
void setActiveChannel (int ch)
 
void setButtonsIcons ()
 
void slot_autoLevelsWidget_parametersChanged ()
 
void slot_autoLevelsWidgetAllChannels_parametersChanged ()
 
void slot_buttonAutoLevels_clicked ()
 
void slot_buttonAutoLevelsAllChannels_clicked ()
 
void slot_buttonGroupHistogramMode_buttonToggled (QAbstractButton *button, bool checked)
 
void slot_buttonGroupMode_buttonToggled (QAbstractButton *button, bool checked)
 
void slot_comboBoxChannel_activated (int index)
 
void slot_sliderInputLevels_blackPointChanged (qreal value)
 
void slot_sliderInputLevels_gammaChanged (qreal value)
 
void slot_sliderInputLevels_whitePointChanged (qreal value)
 
void slot_sliderOutputLevels_blackPointChanged (qreal value)
 
void slot_sliderOutputLevels_whitePointChanged (qreal value)
 
void slot_spinBoxInputBlackPoint_valueChanged (int value)
 
void slot_spinBoxInputGamma_valueChanged (qreal value)
 
void slot_spinBoxInputWhitePoint_valueChanged (int value)
 
void slot_spinBoxOutputBlackPoint_valueChanged (int value)
 
void slot_spinBoxOutputWhitePoint_valueChanged (int value)
 
void updateHistograms ()
 
void updateHistogramViewChannels ()
 
void updateWidgets ()
 

Private Member Functions

bool event (QEvent *e) override
 

Private Attributes

int m_activeChannel
 
int m_activeChannelMax
 
int m_activeChannelMin
 
KisLevelsCurvem_activeLevelsCurve
 
KisAutoLevelsWidgetm_autoLevelsWidget
 
QScopedPointer< KisHistogramm_channelsHistogram
 
const KoColorSpacem_colorSpace
 
KisPaintDeviceSP m_dev
 
QVector< KisLevelsCurvem_levelsCurves
 
QScopedPointer< KisHistogramm_lightnessHistogram
 
KisLevelsCurve m_lightnessLevelsCurve
 
QPair< int, int > m_lightnessMinMaxRanges
 
Ui::LevelsConfigWidget m_page
 
QVector< VirtualChannelInfom_virtualChannels
 
QVector< QPair< int, int > > m_virtualChannelsMinMaxRanges
 

Additional Inherited Members

- Signals inherited from KisConfigWidget
void sigConfigurationItemChanged ()
 
void sigConfigurationUpdated ()
 
void sigDropLockedConfig (KisPropertiesConfigurationSP p)
 
void sigSaveLockedConfig (KisPropertiesConfigurationSP p)
 
- Protected Member Functions inherited from KisConfigWidget
 KisConfigWidget (QWidget *parent=0, Qt::WindowFlags f=Qt::WindowFlags(), int delay=200)
 

Detailed Description

Definition at line 26 of file KisLevelsConfigWidget.h.

Constructor & Destructor Documentation

◆ KisLevelsConfigWidget()

KisLevelsConfigWidget::KisLevelsConfigWidget ( QWidget * parent,
KisPaintDeviceSP dev,
const KoColorSpace * colorSpace )

Definition at line 55 of file KisLevelsConfigWidget.cpp.

56 : KisConfigWidget(parent)
57 , m_dev(dev)
58 , m_colorSpace(colorSpace)
60 , m_activeLevelsCurve(nullptr)
61 , m_channelsHistogram(nullptr)
62 , m_lightnessHistogram(nullptr)
63{
64 Q_ASSERT(m_dev);
65 Q_ASSERT(m_colorSpace);
66
69
70 m_page.setupUi(this);
71 // In some styles the combo box is higher than the tool buttons so
72 // hiding/unhiding it can make the layout jump in that area.
73 // We set the spacer item height to the same as the combo box
74 m_page.spacer01->changeSize(0, m_page.comboBoxChannel->sizeHint().height(),
75 QSizePolicy::Expanding, QSizePolicy::Fixed);
76
77 // Only enable the "all-channels auto levels" button if the color space
78 // is rgb
79 m_page.buttonAutoLevelsAllChannels->setEnabled(m_colorSpace->colorModelId() == RGBAColorModelID);
80
82
84 for (int i = 0; i < m_virtualChannels.size(); ++i) {
85 m_levelsCurves.append(defaultLevelsCurve);
86 m_levelsCurves[i].setName(m_virtualChannels[i].name());
87 m_page.comboBoxChannel->addItem(m_virtualChannels[i].name(), i);
88 }
89 m_lightnessLevelsCurve.setName(i18nc("Lightness value in Lab color model", "Lightness"));
90
94
97
98 connect(m_page.buttonGroupMode, SIGNAL(buttonToggled(QAbstractButton*, bool)), SLOT(slot_buttonGroupMode_buttonToggled(QAbstractButton*, bool)));
99 connect(m_page.comboBoxChannel, SIGNAL(activated(int)), SLOT(slot_comboBoxChannel_activated(int)));
100 connect(m_page.buttonGroupHistogramMode, SIGNAL(buttonToggled(QAbstractButton*, bool)), SLOT(slot_buttonGroupHistogramMode_buttonToggled(QAbstractButton*, bool)));
101 connect(m_page.buttonScaleHistogramToFit, SIGNAL(clicked()), m_page.widgetHistogram, SLOT(setScaleToFit()));
102 connect(m_page.buttonScaleHistogramToCutLongPeaks, SIGNAL(clicked()), m_page.widgetHistogram, SLOT(setScaleToCutLongPeaks()));
103 connect(m_page.buttonResetAll, SIGNAL(clicked()), SLOT(resetAll()));
104 connect(m_page.buttonResetInputLevels, SIGNAL(clicked()), SLOT(resetInputLevels()));
105 connect(m_page.buttonResetOutputLevels, SIGNAL(clicked()), SLOT(resetOutputLevels()));
106 connect(m_page.buttonResetAllChannels, SIGNAL(clicked()), SLOT(resetAllChannels()));
107 connect(m_page.spinBoxInputBlackPoint, SIGNAL(valueChanged(int)), SLOT(slot_spinBoxInputBlackPoint_valueChanged(int)));
108 connect(m_page.spinBoxInputWhitePoint, SIGNAL(valueChanged(int)), SLOT(slot_spinBoxInputWhitePoint_valueChanged(int)));
109 connect(m_page.spinBoxInputGamma, SIGNAL(valueChanged(qreal)), SLOT(slot_spinBoxInputGamma_valueChanged(qreal)));
110 connect(m_page.spinBoxOutputBlackPoint, SIGNAL(valueChanged(int)), SLOT(slot_spinBoxOutputBlackPoint_valueChanged(int)));
111 connect(m_page.spinBoxOutputWhitePoint, SIGNAL(valueChanged(int)), SLOT(slot_spinBoxOutputWhitePoint_valueChanged(int)));
112 connect(m_page.sliderInputLevels, SIGNAL(blackPointChanged(qreal)), SLOT(slot_sliderInputLevels_blackPointChanged(qreal)));
113 connect(m_page.sliderInputLevels, SIGNAL(whitePointChanged(qreal)), SLOT(slot_sliderInputLevels_whitePointChanged(qreal)));
114 connect(m_page.sliderInputLevels, SIGNAL(gammaChanged(qreal)), SLOT(slot_sliderInputLevels_gammaChanged(qreal)));
115 connect(m_page.sliderOutputLevels, SIGNAL(blackPointChanged(qreal)), SLOT(slot_sliderOutputLevels_blackPointChanged(qreal)));
116 connect(m_page.sliderOutputLevels, SIGNAL(whitePointChanged(qreal)), SLOT(slot_sliderOutputLevels_whitePointChanged(qreal)));
117 connect(m_page.buttonAutoLevels, SIGNAL(clicked()), SLOT(slot_buttonAutoLevels_clicked()));
118 connect(m_page.buttonAutoLevelsAllChannels, SIGNAL(clicked()), SLOT(slot_buttonAutoLevelsAllChannels_clicked()));
119}
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
KisConfigWidget(QWidget *parent=0, Qt::WindowFlags f=Qt::WindowFlags(), int delay=200)
KisLevelsCurve m_lightnessLevelsCurve
void slot_sliderInputLevels_blackPointChanged(qreal value)
void slot_spinBoxOutputWhitePoint_valueChanged(int value)
const KoColorSpace * m_colorSpace
void slot_buttonGroupHistogramMode_buttonToggled(QAbstractButton *button, bool checked)
void slot_sliderOutputLevels_blackPointChanged(qreal value)
void slot_sliderInputLevels_gammaChanged(qreal value)
KisLevelsCurve * m_activeLevelsCurve
void slot_sliderOutputLevels_whitePointChanged(qreal value)
void slot_buttonGroupMode_buttonToggled(QAbstractButton *button, bool checked)
void slot_spinBoxInputWhitePoint_valueChanged(int value)
QScopedPointer< KisHistogram > m_lightnessHistogram
QVector< VirtualChannelInfo > m_virtualChannels
void slot_sliderInputLevels_whitePointChanged(qreal value)
void slot_comboBoxChannel_activated(int index)
void slot_spinBoxInputBlackPoint_valueChanged(int value)
Ui::LevelsConfigWidget m_page
void slot_spinBoxOutputBlackPoint_valueChanged(int value)
QPair< int, int > m_lightnessMinMaxRanges
QVector< KisLevelsCurve > m_levelsCurves
QScopedPointer< KisHistogram > m_channelsHistogram
void slot_spinBoxInputGamma_valueChanged(qreal value)
This class holds the parameters for a levels adjustment. It is modeled after KisCubicCurve and has si...
void setName(const QString &newName)
Set the name associated with this levels info object. This allows us to carry around a display name f...
virtual KoID colorModelId() const =0
const char * name(StandardAction id)
QVector< VirtualChannelInfo > getVirtualChannels(const KoColorSpace *cs, int maxChannels, bool supportsLightness, bool supportsHue, bool supportsSaturation)

References KoColorSpace::colorModelId(), computeChannelsMinMaxRanges(), connect(), KisLevelsFilterConfiguration::defaultLevelsCurve(), KisMultiChannelUtils::getVirtualChannels(), m_activeChannelMax, m_activeChannelMin, m_activeLevelsCurve, m_colorSpace, m_dev, m_levelsCurves, m_lightnessLevelsCurve, m_lightnessMinMaxRanges, m_page, m_virtualChannels, resetAll(), resetAllChannels(), resetInputLevels(), resetOutputLevels(), RGBAColorModelID, setButtonsIcons(), KisLevelsCurve::setName(), slot_buttonAutoLevels_clicked(), slot_buttonAutoLevelsAllChannels_clicked(), slot_buttonGroupHistogramMode_buttonToggled(), slot_buttonGroupMode_buttonToggled(), slot_comboBoxChannel_activated(), slot_sliderInputLevels_blackPointChanged(), slot_sliderInputLevels_gammaChanged(), slot_sliderInputLevels_whitePointChanged(), slot_sliderOutputLevels_blackPointChanged(), slot_sliderOutputLevels_whitePointChanged(), slot_spinBoxInputBlackPoint_valueChanged(), slot_spinBoxInputGamma_valueChanged(), slot_spinBoxInputWhitePoint_valueChanged(), slot_spinBoxOutputBlackPoint_valueChanged(), slot_spinBoxOutputWhitePoint_valueChanged(), updateHistograms(), and updateWidgets().

◆ ~KisLevelsConfigWidget()

KisLevelsConfigWidget::~KisLevelsConfigWidget ( )
override

Definition at line 121 of file KisLevelsConfigWidget.cpp.

122{}

Member Function Documentation

◆ computeChannelsMinMaxRanges

void KisLevelsConfigWidget::computeChannelsMinMaxRanges ( )
privateslot

Definition at line 250 of file KisLevelsConfigWidget.cpp.

251{
253 for (int i = 0; i < m_virtualChannels.size(); ++i) {
254 const VirtualChannelInfo &channel = m_virtualChannels[i];
255 const KoChannelInfo::enumChannelValueType valueType = channel.valueType();
256
257 switch (valueType) {
260 break;
263 break;
264 default:
265 //Hack Alert: should be changed to float
266 int min, max;
268 if (i < m_dev->colorSpace()->channels().length()) {
269 min = m_colorSpace->channels()[i]->getUIMin();
270 max = m_colorSpace->channels()[i]->getUIMax();
271 } else {
272 // it must be "Hue", "Saturation" or other "channel" that isn't actually accessible in the color space
273 min = 0;
274 // specific number apparently doesn't matter,
275 // if there is 255, it will work just fine, too
276 max = 100;
277 }
278 } else {
279 min = 0;
280 max = 100;
281 }
283 break;
284 }
285 }
286 for (int i = 0; i < m_virtualChannels.size(); ++i) {
289 break;
290 }
291 }
292}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
QVector< QPair< int, int > > m_virtualChannelsMinMaxRanges
enumChannelValueType
enum to define the value of the channel
@ UINT8
use this for an unsigned integer 8bits channel
@ UINT16
use this for an integer 16bits channel
QList< KoChannelInfo * > channels
KoChannelInfo::enumChannelValueType valueType() const
T min(T a, T b, T c)
constexpr std::enable_if< sizeof...(values)==0, size_t >::type max()

References KoColorSpace::channels, CMYKAColorModelID, KoColorSpace::colorModelId(), LABAColorModelID, length(), m_colorSpace, m_lightnessMinMaxRanges, m_virtualChannels, m_virtualChannelsMinMaxRanges, VirtualChannelInfo::REAL, KoChannelInfo::UINT16, KoChannelInfo::UINT8, and VirtualChannelInfo::valueType().

◆ configuration()

KisPropertiesConfigurationSP KisLevelsConfigWidget::configuration ( ) const
overridevirtual
Returns
the configuration

Implements KisConfigWidget.

Definition at line 124 of file KisLevelsConfigWidget.cpp.

125{
128
129 KIS_ASSERT_RECOVER(m_activeChannel < m_levelsCurves.size()) { return config; }
130
133 config->setUseLightnessMode(m_page.buttonLightnessMode->isChecked());
134 config->setShowLogarithmicHistogram(m_page.buttonLogarithmicHistogram->isChecked());
135
136 return config;
137}
static KisResourcesInterfaceSP instance()
void setLevelsCurves(const QVector< KisLevelsCurve > &newLevelsCurves)
void setShowLogarithmicHistogram(bool newShowLogarithmicHistogram)
void setUseLightnessMode(bool newUseLightnessMode)
void setLightnessLevelsCurve(const KisLevelsCurve &newLightnessLevelsCurve)
#define KIS_ASSERT_RECOVER(cond)
Definition kis_assert.h:55

References KisGlobalResourcesInterface::instance(), KIS_ASSERT_RECOVER, m_activeChannel, m_levelsCurves, m_lightnessLevelsCurve, m_page, m_virtualChannels, KisLevelsFilterConfiguration::setLevelsCurves(), KisLevelsFilterConfiguration::setLightnessLevelsCurve(), KisLevelsFilterConfiguration::setShowLogarithmicHistogram(), and KisLevelsFilterConfiguration::setUseLightnessMode().

◆ event()

bool KisLevelsConfigWidget::event ( QEvent * e)
overrideprivate

Definition at line 698 of file KisLevelsConfigWidget.cpp.

699{
700 if (e->type() == QEvent::StyleChange) {
701 m_page.spacer01->changeSize(0, m_page.comboBoxChannel->sizeHint().height(),
702 QSizePolicy::Expanding, QSizePolicy::Fixed);
703 }
704 return QWidget::event(e);
705}

References m_page.

◆ resetAll

void KisLevelsConfigWidget::resetAll ( )
privateslot

Definition at line 209 of file KisLevelsConfigWidget.cpp.

210{
214}
void sigConfigurationItemChanged()
void resetAll()
Resets the input and output levels (and gamma)

References m_activeLevelsCurve, KisLevelsCurve::resetAll(), KisConfigWidget::sigConfigurationItemChanged(), and updateWidgets().

◆ resetAllChannels

void KisLevelsConfigWidget::resetAllChannels ( )
privateslot

Definition at line 230 of file KisLevelsConfigWidget.cpp.

231{
232 for (KisLevelsCurve &levelsCurve : m_levelsCurves) {
233 levelsCurve.resetAll();
234 }
237}

References m_levelsCurves, KisConfigWidget::sigConfigurationItemChanged(), and updateWidgets().

◆ resetInputLevels

void KisLevelsConfigWidget::resetInputLevels ( )
privateslot

◆ resetOutputLevels

void KisLevelsConfigWidget::resetOutputLevels ( )
privateslot

◆ setActiveChannel

void KisLevelsConfigWidget::setActiveChannel ( int ch)
privateslot

◆ setButtonsIcons

void KisLevelsConfigWidget::setButtonsIcons ( )
privateslot

Definition at line 436 of file KisLevelsConfigWidget.cpp.

437{
438 m_page.buttonLightnessMode->setIcon(KisIconUtils::loadIcon("color-adjustment-mode-lightness"));
439 m_page.buttonAllChannelsMode->setIcon(KisIconUtils::loadIcon("color-adjustment-mode-channels"));
440 m_page.buttonLinearHistogram->setIcon(KisIconUtils::loadIcon("histogram-linear"));
441 m_page.buttonLogarithmicHistogram->setIcon(KisIconUtils::loadIcon("histogram-logarithmic"));
442 m_page.buttonScaleHistogramToFit->setIcon(KisIconUtils::loadIcon("histogram-show-all"));
443 m_page.buttonScaleHistogramToCutLongPeaks->setIcon(KisIconUtils::loadIcon("histogram-show-best"));
444 m_page.buttonResetAll->setIcon(KisIconUtils::loadIcon("reload-preset"));
445 m_page.buttonResetInputLevels->setIcon(KisIconUtils::loadIcon("reload-preset"));
446 m_page.buttonResetOutputLevels->setIcon(KisIconUtils::loadIcon("reload-preset"));
447 m_page.buttonResetAllChannels->setIcon(KisIconUtils::loadIcon("reload-preset"));
448 m_page.buttonAutoLevels->setIcon(KisIconUtils::loadIcon("autolevels"));
449 m_page.buttonAutoLevelsAllChannels->setIcon(KisIconUtils::loadIcon("autolevels"));
450}
QIcon loadIcon(const QString &name)

References KisIconUtils::loadIcon(), and m_page.

◆ setConfiguration()

void KisLevelsConfigWidget::setConfiguration ( const KisPropertiesConfigurationSP config)
overridevirtual
Parameters
configthe configuration for this configuration widget.

HACK ALERT: our configuration factory generates default configuration with nTransfers==0. Catching it here. Just set everything to defaults instead. Also reset to default if the mode is not "advanced" but the configuration was created for a different colorspace.

Implements KisConfigWidget.

Definition at line 139 of file KisLevelsConfigWidget.cpp.

140{
141 const KisLevelsFilterConfiguration *filterConfig =
142 dynamic_cast<const KisLevelsFilterConfiguration *>(config.data());
143 KIS_SAFE_ASSERT_RECOVER_RETURN(filterConfig);
144
145 {
146 KisSignalsBlocker blocker(this, m_page.buttonLightnessMode, m_page.buttonAllChannelsMode);
147
148 if (filterConfig->levelsCurves().empty() || filterConfig->levelsCurves().size() > m_virtualChannels.size()) {
156 KisPropertiesConfigurationSP defaultConfiguration =
158 KisLevelsFilterConfiguration *defaultFilterConfig =
159 dynamic_cast<KisLevelsFilterConfiguration*>(defaultConfiguration.data());
160 KIS_SAFE_ASSERT_RECOVER_RETURN(defaultFilterConfig);
161
162 if (filterConfig->levelsCurves().size() > m_virtualChannels.size()) {
163 QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("The current configuration was created for a different colorspace and cannot be used.\nThe channels will be reset."));
164 warnKrita << "WARNING: trying to load levels info with invalid number of channels!";
165 warnKrita << "WARNING: expected:" << m_virtualChannels.size();
166 warnKrita << "WARNING: got:" << filterConfig->levelsCurves().size();
167 }
168
169 defaultFilterConfig->setLightnessLevelsCurve(filterConfig->lightnessLevelsCurve());
170 defaultFilterConfig->setUseLightnessMode(filterConfig->useLightnessMode());
171 defaultFilterConfig->setShowLogarithmicHistogram(filterConfig->showLogarithmicHistogram());
172 setConfiguration(defaultConfiguration);
173
174 return;
175 }
176
177 if (filterConfig->levelsCurves().size() < m_virtualChannels.size()) {
178 // The configuration does not cover all our channels.
179 // This happens when loading a document from an older version, which supported fewer channels.
180 // Reset to make sure the unspecified channels have their default values.
182 }
183
184 for (int ch = 0; ch < filterConfig->levelsCurves().size(); ++ch) {
185 m_levelsCurves[ch] = filterConfig->levelsCurves()[ch];
186 }
187
189
190
191 if (filterConfig->showLogarithmicHistogram()) {
192 m_page.buttonLogarithmicHistogram->setChecked(true);
193 } else {
194 m_page.buttonLinearHistogram->setChecked(true);
195 }
196
197 if (filterConfig->useLightnessMode()) {
198 m_page.buttonLightnessMode->setChecked(true);
199 slot_buttonGroupMode_buttonToggled(m_page.buttonLightnessMode, true);
200 } else {
201 m_page.buttonAllChannelsMode->setChecked(true);
202 slot_buttonGroupMode_buttonToggled(m_page.buttonAllChannelsMode, true);
203 }
204 }
205
207}
void setConfiguration(const KisPropertiesConfigurationSP config) override
const KisLevelsCurve lightnessLevelsCurve() const
const QVector< KisLevelsCurve > levelsCurves() const
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define warnKrita
Definition kis_debug.h:87
int size(const Forest< T > &forest)
Definition KisForest.h:1232

References KisSharedPtr< T >::data(), KisGlobalResourcesInterface::instance(), KIS_SAFE_ASSERT_RECOVER_RETURN, KisLevelsFilterConfiguration::levelsCurves(), KisLevelsFilterConfiguration::lightnessLevelsCurve(), m_levelsCurves, m_lightnessLevelsCurve, m_page, m_virtualChannels, resetAllChannels(), setConfiguration(), KisLevelsFilterConfiguration::setLightnessLevelsCurve(), KisLevelsFilterConfiguration::setShowLogarithmicHistogram(), KisLevelsFilterConfiguration::setUseLightnessMode(), KisLevelsFilterConfiguration::showLogarithmicHistogram(), KisConfigWidget::sigConfigurationItemChanged(), slot_buttonGroupMode_buttonToggled(), KisLevelsFilterConfiguration::useLightnessMode(), and warnKrita.

◆ slot_autoLevelsWidget_parametersChanged

void KisLevelsConfigWidget::slot_autoLevelsWidget_parametersChanged ( )
privateslot

Definition at line 707 of file KisLevelsConfigWidget.cpp.

708{
709 KisHistogram *histogram;
710 int channel;
711 bool isCMYK = false;
712
713 if (m_page.buttonLightnessMode->isChecked() ||
715 histogram = m_lightnessHistogram.data();
716 channel = 0;
717 } else {
718 histogram = m_channelsHistogram.data();
719 channel = m_virtualChannels[m_activeChannel].pixelIndex();
721 }
722
723 // Output colors
726 const KoColor shadowsColor = m_autoLevelsWidget->outputShadowsColor().convertedTo(outputColorsColorSpace);
727 const KoColor highlightsColor = m_autoLevelsWidget->outputHighlightsColor().convertedTo(outputColorsColorSpace);
728 const KoColor midtonesColor = m_autoLevelsWidget->outputMidtonesColor().convertedTo(outputColorsColorSpace);
729 QVector<float> shadowsNormalizedColor(outputColorsColorSpace->channelCount());
730 QVector<float> highlightsNormalizedColor(outputColorsColorSpace->channelCount());
731 QVector<float> midtonesNormalizedColor(outputColorsColorSpace->channelCount());
732 outputColorsColorSpace->normalisedChannelsValue(shadowsColor.data(), shadowsNormalizedColor);
733 outputColorsColorSpace->normalisedChannelsValue(highlightsColor.data(), highlightsNormalizedColor);
734 outputColorsColorSpace->normalisedChannelsValue(midtonesColor.data(), midtonesNormalizedColor);
735 const qreal shadowsOutput = isCMYK ? 1.0 - highlightsNormalizedColor[0] : shadowsNormalizedColor[0];
736 const qreal highlightsOutput = isCMYK ? 1.0 - shadowsNormalizedColor[0] : highlightsNormalizedColor[0];
737 const qreal midtonesOutput = midtonesNormalizedColor[0];
738
739 QVector<KisAutoLevels::ChannelHistogram> channelsHistograms{{histogram, channel}};
740
743 {histogram, channel},
744 channelsHistograms,
750 {shadowsOutput},
751 {highlightsOutput},
752 {midtonesOutput}
753 )[0];
754
757}
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
KisAutoLevels::MidtonesAdjustmentMethod midtonesAdjustmentMethod() const
Get the method used to adjust the midtones.
KoColor outputMidtonesColor() const
Get the color used to move the midtones towards.
qreal midtonesAdjustmentAmount() const
Get how much the reference midtone point is deviated from the center of the histogram to the median/m...
KoColor outputShadowsColor() const
Get the color used to move the shadows towards.
KoColor outputHighlightsColor() const
Get the color used to move the highlights towards.
qreal highlightsClipping() const
Get the normalized percentage used to clip the highlights.
qreal shadowsClipping() const
Get the normalized percentage used to clip the shadows.
qreal maximumInputBlackAndWhiteOffset() const
Get the normalized maximum value that the black/white point can be moved from the default position of...
KisAutoLevelsWidget * m_autoLevelsWidget
virtual quint32 channelCount() const =0
virtual KoID colorDepthId() const =0
virtual void normalisedChannelsValue(const quint8 *pixel, QVector< float > &channels) const =0
KoColor convertedTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
Definition KoColor.cpp:163
quint8 * data()
Definition KoColor.h:144
QString id() const
Definition KoID.cpp:63
QVector< KisLevelsCurve > adjustMonochromaticContrast(ChannelHistogram lightnessHistogram, QVector< ChannelHistogram > &channelsHistograms, qreal shadowsClipping, qreal highlightsClipping, qreal maximumInputBlackAndWhiteOffset, MidtonesAdjustmentMethod midtonesAdjustmentMethod, qreal midtonesAdjustmentAmount, const QVector< qreal > &outputBlackPoints, const QVector< qreal > &outputWhitePoints, const QVector< qreal > &outputMidtones)
Creates a KisLevelsCurve for every channel in "channelsHistograms". Computes the input black and whit...
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()

References KisAutoLevels::adjustMonochromaticContrast(), KoColorSpace::channelCount(), CMYKAColorModelID, KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KoColorSpaceRegistry::colorSpace(), KoColor::convertedTo(), KoColor::data(), GrayAColorModelID, KisAutoLevelsWidget::highlightsClipping(), KoID::id(), KoColorSpaceRegistry::instance(), VirtualChannelInfo::LIGHTNESS, m_activeChannel, m_activeLevelsCurve, m_autoLevelsWidget, m_channelsHistogram, m_colorSpace, m_lightnessHistogram, m_page, m_virtualChannels, KisAutoLevelsWidget::maximumInputBlackAndWhiteOffset(), KisAutoLevelsWidget::midtonesAdjustmentAmount(), KisAutoLevelsWidget::midtonesAdjustmentMethod(), KoColorSpace::normalisedChannelsValue(), KisAutoLevelsWidget::outputHighlightsColor(), KisAutoLevelsWidget::outputMidtonesColor(), KisAutoLevelsWidget::outputShadowsColor(), KisAutoLevelsWidget::shadowsClipping(), KisConfigWidget::sigConfigurationItemChanged(), and updateWidgets().

◆ slot_autoLevelsWidgetAllChannels_parametersChanged

void KisLevelsConfigWidget::slot_autoLevelsWidgetAllChannels_parametersChanged ( )
privateslot

Definition at line 759 of file KisLevelsConfigWidget.cpp.

760{
761 // histograms
763 for (const VirtualChannelInfo &virtualChannelInfo : m_virtualChannels) {
764 if (virtualChannelInfo.type() == VirtualChannelInfo::REAL && !virtualChannelInfo.isAlpha()) {
765 channelsHistograms.append({m_channelsHistogram.data(), virtualChannelInfo.pixelIndex()});
766 }
767 }
768
769 // Output colors
770 QVector<qreal> shadowsOutput, highlightsOutput, midtonesOutput;
774 QVector<float> shadowsNormalizedColor(m_colorSpace->channelCount());
775 QVector<float> highlightsNormalizedColor(m_colorSpace->channelCount());
776 QVector<float> midtonesNormalizedColor(m_colorSpace->channelCount());
777 m_colorSpace->normalisedChannelsValue(shadowsColor.data(), shadowsNormalizedColor);
778 m_colorSpace->normalisedChannelsValue(highlightsColor.data(), highlightsNormalizedColor);
779 m_colorSpace->normalisedChannelsValue(midtonesColor.data(), midtonesNormalizedColor);
780 for (const KisAutoLevels::ChannelHistogram &channelHistogram : channelsHistograms) {
781 shadowsOutput.append(shadowsNormalizedColor[channelHistogram.channel]);
782 highlightsOutput.append(highlightsNormalizedColor[channelHistogram.channel]);
783 midtonesOutput.append(midtonesNormalizedColor[channelHistogram.channel]);
784 }
785
786 // get levels parameters
787 QVector<KisLevelsCurve> levelsCurves;
789 levelsCurves =
791 channelsHistograms,
797 shadowsOutput,
798 highlightsOutput,
799 midtonesOutput
800 );
801 // get min black point and max white point
802 qreal minBlackPoint = 1.0;
803 qreal maxWhitePoint = 0.0;
804 for (const KisLevelsCurve &levelsCurve : levelsCurves) {
805 minBlackPoint = qMin(levelsCurve.inputBlackPoint(), minBlackPoint);
806 maxWhitePoint = qMax(levelsCurve.inputWhitePoint(), maxWhitePoint);
807 }
808 for (KisLevelsCurve &levelsCurve : levelsCurves) {
809 levelsCurve.setInputBlackPoint(minBlackPoint);
810 levelsCurve.setInputWhitePoint(maxWhitePoint);
811 }
812 } else {
813 levelsCurves =
815 channelsHistograms,
821 shadowsOutput,
822 highlightsOutput,
823 midtonesOutput
824 );
825 }
826
827 // Set parameters
828 for (int i = 0, j = 0; i < m_virtualChannels.size(); ++i) {
829 if (m_virtualChannels[i].type() == VirtualChannelInfo::REAL && !m_virtualChannels[i].isAlpha()) {
830 m_levelsCurves[i] = levelsCurves[j];
831 ++j;
832 }
833 }
836}
KisAutoLevels::ShadowsAndHighlightsAdjustmentMethod shadowsAndHighlightsAdjustmentMethod() const
Get the method used to adjust the contrast.
QVector< KisLevelsCurve > adjustPerChannelContrast(QVector< ChannelHistogram > &channelsHistograms, qreal shadowsClipping, qreal highlightsClipping, qreal maximumInputBlackAndWhiteOffset, MidtonesAdjustmentMethod midtonesAdjustmentMethod, qreal midtonesAdjustmentAmount, const QVector< qreal > &outputBlackPoints, const QVector< qreal > &outputWhitePoints, const QVector< qreal > &outputMidtones)
Creates a KisLevelsCurve for every channel in "channelsHistograms". Computes the input black and whit...
@ ShadowsAndHighlightsAdjustmentMethod_MonochromaticContrast
Convenience class that associates a KisHistogram and a channel index. This is useful because setting ...

References KisAutoLevels::adjustPerChannelContrast(), KoColorSpace::channelCount(), KoColor::convertedTo(), KoColor::data(), KisAutoLevelsWidget::highlightsClipping(), m_autoLevelsWidget, m_channelsHistogram, m_colorSpace, m_levelsCurves, m_virtualChannels, KisAutoLevelsWidget::maximumInputBlackAndWhiteOffset(), KisAutoLevelsWidget::midtonesAdjustmentAmount(), KisAutoLevelsWidget::midtonesAdjustmentMethod(), KoColorSpace::normalisedChannelsValue(), KisAutoLevelsWidget::outputHighlightsColor(), KisAutoLevelsWidget::outputMidtonesColor(), KisAutoLevelsWidget::outputShadowsColor(), VirtualChannelInfo::REAL, KisAutoLevelsWidget::shadowsAndHighlightsAdjustmentMethod(), KisAutoLevels::ShadowsAndHighlightsAdjustmentMethod_MonochromaticContrast, KisAutoLevelsWidget::shadowsClipping(), KisConfigWidget::sigConfigurationItemChanged(), and updateWidgets().

◆ slot_buttonAutoLevels_clicked

void KisLevelsConfigWidget::slot_buttonAutoLevels_clicked ( )
privateslot

Definition at line 578 of file KisLevelsConfigWidget.cpp.

579{
580 KisLevelsCurve previousLevelsCurve = *m_activeLevelsCurve;
581
582 KoDialog *autolevelsDialog = new KoDialog(this);
583
584 m_autoLevelsWidget = new KisAutoLevelsWidget(autolevelsDialog);
585 // Lock contrast method
588 );
590 // Set some default parameters based on the selected channel. These were
591 // selected empirically, there is no strong reason why they should be like this
592 if (m_page.buttonLightnessMode->isChecked() ||
601 if (m_virtualChannels[m_activeChannel].pixelIndex() == 0 ||
602 m_virtualChannels[m_activeChannel].pixelIndex() == 1 ||
603 m_virtualChannels[m_activeChannel].pixelIndex() == 2) {
605 }
606 }
607 // Set the output colors
610 m_autoLevelsWidget->setShadowsColor(KoColor(Qt::black, outputColorsColorSpace));
611 m_autoLevelsWidget->setHighlightsColor(KoColor(Qt::white, outputColorsColorSpace));
612 // Ensure that the midtone color has 50% value
613 QVector<float> normalizedMidtonesColor{0.5, 1.0};
614 KoColor midtonesColor(outputColorsColorSpace);
615 outputColorsColorSpace->fromNormalisedChannelsValue(midtonesColor.data(), normalizedMidtonesColor);
616 m_autoLevelsWidget->setMidtonesColor(midtonesColor);
617
618 connect(m_autoLevelsWidget, SIGNAL(parametersChanged()), SLOT(slot_autoLevelsWidget_parametersChanged()));
620
621 autolevelsDialog->setCaption(i18nc("@title:window", "Auto Levels"));
622 autolevelsDialog->setMainWidget(m_autoLevelsWidget);
623 autolevelsDialog->setAttribute(Qt::WA_DeleteOnClose);
624 connect(autolevelsDialog, &QDialog::rejected,
625 [this, previousLevelsCurve]()
626 {
627 *m_activeLevelsCurve = previousLevelsCurve;
630 }
631 );
632 connect(autolevelsDialog, &QDialog::finished, [this](){ setEnabled(true); });
633
634 setEnabled(false);
635 autolevelsDialog->setEnabled(true);
636
637 autolevelsDialog->show();
638 autolevelsDialog->raise();
639 autolevelsDialog->activateWindow();
640}
A widget that allows to select a combination of auto levels parameters.
void setMidtonesAdjustmentAmount(qreal newMidtonesAdjustmentAmount)
Set how much the reference midtone point is deviated from the center of the histogram to the median/m...
void setMidtonesColor(const KoColor &newMidtonesColor)
Set the color used to move the midtones towards.
void setShadowsColor(const KoColor &newShadowsColor)
Set the color used to move the shadows towards.
void setMaximumInputBlackAndWhiteOffset(qreal newMaximumInputBlackAndWhiteOffset)
Set the normalized maximum value that the black/white point can be moved from the default position of...
void setShadowsAndHighlightsAdjustmentMethod(KisAutoLevels::ShadowsAndHighlightsAdjustmentMethod newMethod)
Set the method used to adjust the contrast.
void setMidtonesAdjustmentMethod(KisAutoLevels::MidtonesAdjustmentMethod newMethod)
Set the method used to adjust the midtones.
void setHighlightsColor(const KoColor &newHighlightsColor)
Set the color used to move the highlights towards.
void lockShadowsAndHighlightsAdjustmentMethod()
Disables the contrast method combo box. Use this when only one of the methods makes sense.
virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector< float > &values) const =0
A dialog base class with standard buttons and predefined layouts.
Definition KoDialog.h:116
void setMainWidget(QWidget *widget)
Definition KoDialog.cpp:354
virtual void setCaption(const QString &caption)
Definition KoDialog.cpp:498
@ MidtonesAdjustmentMethod_UseMedian

References CMYKAColorModelID, KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KoColorSpaceRegistry::colorSpace(), connect(), KoColor::data(), KoColorSpace::fromNormalisedChannelsValue(), GrayAColorModelID, KoID::id(), KoColorSpaceRegistry::instance(), LABAColorModelID, VirtualChannelInfo::LIGHTNESS, KisAutoLevelsWidget::lockShadowsAndHighlightsAdjustmentMethod(), m_activeChannel, m_activeLevelsCurve, m_autoLevelsWidget, m_colorSpace, m_page, m_virtualChannels, KisAutoLevels::MidtonesAdjustmentMethod_UseMedian, KoDialog::setCaption(), KisAutoLevelsWidget::setHighlightsColor(), KoDialog::setMainWidget(), KisAutoLevelsWidget::setMaximumInputBlackAndWhiteOffset(), KisAutoLevelsWidget::setMidtonesAdjustmentAmount(), KisAutoLevelsWidget::setMidtonesAdjustmentMethod(), KisAutoLevelsWidget::setMidtonesColor(), KisAutoLevelsWidget::setShadowsAndHighlightsAdjustmentMethod(), KisAutoLevelsWidget::setShadowsColor(), KisAutoLevels::ShadowsAndHighlightsAdjustmentMethod_MonochromaticContrast, KisConfigWidget::sigConfigurationItemChanged(), slot_autoLevelsWidget_parametersChanged(), and updateWidgets().

◆ slot_buttonAutoLevelsAllChannels_clicked

void KisLevelsConfigWidget::slot_buttonAutoLevelsAllChannels_clicked ( )
privateslot

Definition at line 642 of file KisLevelsConfigWidget.cpp.

643{
644 // We can not use the copy constructor here since it makes use of implicit
645 // sharing. We maintain a pointer to the active levels info in m_levelsCurves.
646 // So, if we change an element of m_levelsCurves that would create a new
647 // vector and the pointer will be invalidated
648 QVector<KisLevelsCurve> previousLevelsCurves;
649 for (const KisLevelsCurve &levelsCurve : m_levelsCurves) {
650 previousLevelsCurves.append(levelsCurve);
651 }
652
653 KoDialog *autolevelsDialog = new KoDialog(this);
654
655 m_autoLevelsWidget = new KisAutoLevelsWidget(autolevelsDialog);
658 );
659
663 // Ensure that the midtone color has 50% value
664 QVector<float> normalizedMidtonesColor{0.5, 0.5, 0.5, 1.0};
665 KoColor midtonesColor(m_colorSpace);
666 m_colorSpace->fromNormalisedChannelsValue(midtonesColor.data(), normalizedMidtonesColor);
667 m_autoLevelsWidget->setMidtonesColor(midtonesColor);
668
671
672 autolevelsDialog->setCaption(i18nc("@title:window", "Auto Levels"));
673 autolevelsDialog->setMainWidget(m_autoLevelsWidget);
674 autolevelsDialog->setAttribute(Qt::WA_DeleteOnClose);
675 connect(autolevelsDialog, &QDialog::rejected,
676 [this, previousLevelsCurves]()
677 {
678 // We maintain a pointer to the active levels info in m_levelsCurves
679 // so we use this loop instead of the assignment operator to avoid
680 // invalidation of the pointer
681 for (int i = 0; i < m_levelsCurves.size(); ++i) {
682 m_levelsCurves[i] = previousLevelsCurves[i];
683 }
686 }
687 );
688 connect(autolevelsDialog, &QDialog::finished, [this](){ setEnabled(true); });
689
690 setEnabled(false);
691 autolevelsDialog->setEnabled(true);
692
693 autolevelsDialog->show();
694 autolevelsDialog->raise();
695 autolevelsDialog->activateWindow();
696}
void slot_autoLevelsWidgetAllChannels_parametersChanged()

References connect(), KoColor::data(), KoColorSpace::fromNormalisedChannelsValue(), m_autoLevelsWidget, m_colorSpace, m_levelsCurves, KoDialog::setCaption(), KisAutoLevelsWidget::setHighlightsColor(), KoDialog::setMainWidget(), KisAutoLevelsWidget::setMidtonesColor(), KisAutoLevelsWidget::setShadowsAndHighlightsAdjustmentMethod(), KisAutoLevelsWidget::setShadowsColor(), KisAutoLevels::ShadowsAndHighlightsAdjustmentMethod_MonochromaticContrast, KisConfigWidget::sigConfigurationItemChanged(), slot_autoLevelsWidgetAllChannels_parametersChanged(), and updateWidgets().

◆ slot_buttonGroupHistogramMode_buttonToggled

void KisLevelsConfigWidget::slot_buttonGroupHistogramMode_buttonToggled ( QAbstractButton * button,
bool checked )
privateslot

Definition at line 478 of file KisLevelsConfigWidget.cpp.

479{
480 if (!checked) {
481 return;
482 }
483 m_page.widgetHistogram->setLogarithmic(button == m_page.buttonLogarithmicHistogram);
484}
QString button(const QWheelEvent &ev)

References button(), and m_page.

◆ slot_buttonGroupMode_buttonToggled

◆ slot_comboBoxChannel_activated

void KisLevelsConfigWidget::slot_comboBoxChannel_activated ( int index)
privateslot

Definition at line 471 of file KisLevelsConfigWidget.cpp.

472{
473 const int virtualChannel = m_page.comboBoxChannel->itemData(index).toInt();
474 setActiveChannel(virtualChannel);
476}

References m_page, setActiveChannel(), and updateHistogramViewChannels().

◆ slot_sliderInputLevels_blackPointChanged

void KisLevelsConfigWidget::slot_sliderInputLevels_blackPointChanged ( qreal value)
privateslot

Definition at line 538 of file KisLevelsConfigWidget.cpp.

539{
540 KisSignalsBlocker blocker(m_page.spinBoxInputBlackPoint);
542 m_page.spinBoxInputBlackPoint->setValue(deNormalizeValue(value, m_activeChannelMin, m_activeChannelMax));
544}
float value(const T *src, size_t ch)
static int deNormalizeValue(qreal value, int min, int max)
void setInputBlackPoint(qreal newInputBlackPoint)
Set the input black point.

References deNormalizeValue(), m_activeChannelMax, m_activeChannelMin, m_activeLevelsCurve, m_page, KisLevelsCurve::setInputBlackPoint(), KisConfigWidget::sigConfigurationItemChanged(), and value().

◆ slot_sliderInputLevels_gammaChanged

void KisLevelsConfigWidget::slot_sliderInputLevels_gammaChanged ( qreal value)
privateslot

Definition at line 554 of file KisLevelsConfigWidget.cpp.

555{
556 KisSignalsBlocker blocker(m_page.spinBoxInputGamma);
558 m_page.spinBoxInputGamma->setValue(value);
560}
void setInputGamma(qreal newInputGamma)
Set the gamma value.

References m_activeLevelsCurve, m_page, KisLevelsCurve::setInputGamma(), KisConfigWidget::sigConfigurationItemChanged(), and value().

◆ slot_sliderInputLevels_whitePointChanged

void KisLevelsConfigWidget::slot_sliderInputLevels_whitePointChanged ( qreal value)
privateslot

◆ slot_sliderOutputLevels_blackPointChanged

void KisLevelsConfigWidget::slot_sliderOutputLevels_blackPointChanged ( qreal value)
privateslot

Definition at line 562 of file KisLevelsConfigWidget.cpp.

563{
564 KisSignalsBlocker blocker(m_page.spinBoxOutputBlackPoint);
566 m_page.spinBoxOutputBlackPoint->setValue(deNormalizeValue(value, m_activeChannelMin, m_activeChannelMax));
568}
void setOutputBlackPoint(qreal newOutputBlackPoint)
Set the output black point.

References deNormalizeValue(), m_activeChannelMax, m_activeChannelMin, m_activeLevelsCurve, m_page, KisLevelsCurve::setOutputBlackPoint(), KisConfigWidget::sigConfigurationItemChanged(), and value().

◆ slot_sliderOutputLevels_whitePointChanged

void KisLevelsConfigWidget::slot_sliderOutputLevels_whitePointChanged ( qreal value)
privateslot

Definition at line 570 of file KisLevelsConfigWidget.cpp.

571{
572 KisSignalsBlocker blocker(m_page.spinBoxOutputWhitePoint);
574 m_page.spinBoxOutputWhitePoint->setValue(deNormalizeValue(value, m_activeChannelMin, m_activeChannelMax));
576}
void setOutputWhitePoint(qreal newOutputWhitePoint)
Set the output white point.

References deNormalizeValue(), m_activeChannelMax, m_activeChannelMin, m_activeLevelsCurve, m_page, KisLevelsCurve::setOutputWhitePoint(), KisConfigWidget::sigConfigurationItemChanged(), and value().

◆ slot_spinBoxInputBlackPoint_valueChanged

void KisLevelsConfigWidget::slot_spinBoxInputBlackPoint_valueChanged ( int value)
privateslot

Definition at line 486 of file KisLevelsConfigWidget.cpp.

487{
488 if (value >= m_page.spinBoxInputWhitePoint->value()) {
489 m_page.spinBoxInputBlackPoint->setValue(m_page.spinBoxInputWhitePoint->value() - 1);
490 }
491
492 KisSignalsBlocker blocker(m_page.sliderInputLevels);
493 const qreal normalizedValue = normalizeValue(value, m_activeChannelMin, m_activeChannelMax);
494 m_activeLevelsCurve->setInputBlackPoint(normalizedValue);
495 m_page.sliderInputLevels->setBlackPoint(normalizedValue);
497}
static qreal normalizeValue(int value, int min, int max)

References m_activeChannelMax, m_activeChannelMin, m_activeLevelsCurve, m_page, normalizeValue(), KisLevelsCurve::setInputBlackPoint(), KisConfigWidget::sigConfigurationItemChanged(), and value().

◆ slot_spinBoxInputGamma_valueChanged

void KisLevelsConfigWidget::slot_spinBoxInputGamma_valueChanged ( qreal value)
privateslot

Definition at line 512 of file KisLevelsConfigWidget.cpp.

513{
514 KisSignalsBlocker blocker(m_page.sliderInputLevels);
516 m_page.sliderInputLevels->setGamma(value);
518}

References m_activeLevelsCurve, m_page, KisLevelsCurve::setInputGamma(), KisConfigWidget::sigConfigurationItemChanged(), and value().

◆ slot_spinBoxInputWhitePoint_valueChanged

void KisLevelsConfigWidget::slot_spinBoxInputWhitePoint_valueChanged ( int value)
privateslot

Definition at line 499 of file KisLevelsConfigWidget.cpp.

500{
501 if (value <= m_page.spinBoxInputBlackPoint->value()) {
502 m_page.spinBoxInputWhitePoint->setValue(m_page.spinBoxInputBlackPoint->value() + 1);
503 }
504
505 KisSignalsBlocker blocker(m_page.sliderInputLevels);
506 const qreal normalizedValue = normalizeValue(value, m_activeChannelMin, m_activeChannelMax);
507 m_activeLevelsCurve->setInputWhitePoint(normalizedValue);
508 m_page.sliderInputLevels->setWhitePoint(normalizedValue);
510}

References m_activeChannelMax, m_activeChannelMin, m_activeLevelsCurve, m_page, normalizeValue(), KisLevelsCurve::setInputWhitePoint(), KisConfigWidget::sigConfigurationItemChanged(), and value().

◆ slot_spinBoxOutputBlackPoint_valueChanged

void KisLevelsConfigWidget::slot_spinBoxOutputBlackPoint_valueChanged ( int value)
privateslot

Definition at line 520 of file KisLevelsConfigWidget.cpp.

521{
522 KisSignalsBlocker blocker(m_page.sliderOutputLevels);
523 const qreal normalizedValue = normalizeValue(value, m_activeChannelMin, m_activeChannelMax);
525 m_page.sliderOutputLevels->setBlackPoint(normalizedValue);
527}

References m_activeChannelMax, m_activeChannelMin, m_activeLevelsCurve, m_page, normalizeValue(), KisLevelsCurve::setOutputBlackPoint(), KisConfigWidget::sigConfigurationItemChanged(), and value().

◆ slot_spinBoxOutputWhitePoint_valueChanged

void KisLevelsConfigWidget::slot_spinBoxOutputWhitePoint_valueChanged ( int value)
privateslot

Definition at line 529 of file KisLevelsConfigWidget.cpp.

530{
531 KisSignalsBlocker blocker(m_page.sliderOutputLevels);
532 const qreal normalizedValue = normalizeValue(value, m_activeChannelMin, m_activeChannelMax);
534 m_page.sliderOutputLevels->setWhitePoint(normalizedValue);
536}

References m_activeChannelMax, m_activeChannelMin, m_activeLevelsCurve, m_page, normalizeValue(), KisLevelsCurve::setOutputWhitePoint(), KisConfigWidget::sigConfigurationItemChanged(), and value().

◆ updateHistograms

void KisLevelsConfigWidget::updateHistograms ( )
privateslot

Definition at line 371 of file KisLevelsConfigWidget.cpp.

372{
373 QVector<KisHistogram*> histograms;
375 QVector<QVector<int>> channels;
376
377 // Init lightness histogram
378 // This is used in the simple mode and if the lightness virtual channel is selected
380 KoHistogramProducer *lightnessHistogramProducer = new KoGenericLabHistogramProducer();
381 m_lightnessHistogram.reset(new KisHistogram(m_dev, m_dev->exactBounds(), lightnessHistogramProducer, LINEAR));
382 histograms.append(m_lightnessHistogram.data());
383 colorSpaces.append(KoColorSpaceRegistry::instance()->lab16());
384 channels.append(QVector<int>({0}));
385 }
386 // Init channels histogram
387 if (!m_channelsHistogram) {
388 const KoColorSpace *colorSpace = m_colorSpace;
390 if (keys.size() > 0) {
393 histograms.append(m_channelsHistogram.data());
394 colorSpaces.append(colorSpace);
395 channels.append(QVector<int>());
396 }
397 }
398
399 if (histograms.size() > 0) {
400 m_page.widgetHistogram->setup(histograms, colorSpaces, channels);
402 m_page.widgetHistogram->setDefaultColor(Qt::gray);
403 }
404}
QRect exactBounds() const
T get(const QString &id) const
QList< QString > keysCompatibleWith(const KoColorSpace *colorSpace, bool isStrict=false) const
returns a list, sorted by preference: higher preference comes first
static KoHistogramProducerFactoryRegistry * instance()
virtual KoHistogramProducer * generate()=0
Factory method, generates a new KoHistogramProducer.
@ LINEAR
Definition nugrid.h:26

References KisPaintDevice::exactBounds(), KoHistogramProducerFactory::generate(), KoGenericRegistry< T >::get(), KoColorSpaceRegistry::instance(), KoHistogramProducerFactoryRegistry::instance(), KoHistogramProducerFactoryRegistry::keysCompatibleWith(), LINEAR, m_channelsHistogram, m_colorSpace, m_dev, m_lightnessHistogram, m_page, and updateHistogramViewChannels().

◆ updateHistogramViewChannels

void KisLevelsConfigWidget::updateHistogramViewChannels ( )
privateslot

Definition at line 406 of file KisLevelsConfigWidget.cpp.

407{
408 m_page.widgetHistogram->clearChannels();
409
410 if (m_page.buttonLightnessMode->isChecked() ||
413 m_page.widgetHistogram->setChannel(0, 0);
414 }
415 } else {
418 (channelType == VirtualChannelInfo::ALL_COLORS || channelType == VirtualChannelInfo::REAL)) {
419
420 if (channelType == VirtualChannelInfo::ALL_COLORS) {
421 QVector<int> channels;
422 for (const VirtualChannelInfo &channelInfo : m_virtualChannels) {
423 if (channelInfo.type() == VirtualChannelInfo::REAL && !channelInfo.isAlpha()) {
424 channels.append(channelInfo.pixelIndex());
425 }
426 }
427 m_page.widgetHistogram->setChannels(channels, 1);
428
429 } else if (channelType == VirtualChannelInfo::REAL) {
430 m_page.widgetHistogram->setChannel(m_virtualChannels[m_activeChannel].pixelIndex(), 1);
431 }
432 }
433 }
434}

References VirtualChannelInfo::ALL_COLORS, VirtualChannelInfo::LIGHTNESS, m_activeChannel, m_channelsHistogram, m_lightnessHistogram, m_page, m_virtualChannels, and VirtualChannelInfo::REAL.

◆ updateWidgets

void KisLevelsConfigWidget::updateWidgets ( )
privateslot

Definition at line 294 of file KisLevelsConfigWidget.cpp.

295{
296 KisSignalsBlocker blocker1(m_page.comboBoxChannel, m_page.sliderInputLevels, m_page.sliderOutputLevels);
297 KisSignalsBlocker blocker2(m_page.spinBoxInputBlackPoint, m_page.spinBoxInputWhitePoint, m_page.spinBoxInputGamma,
298 m_page.spinBoxOutputBlackPoint, m_page.spinBoxOutputWhitePoint);
299
300 if (m_page.buttonLightnessMode->isChecked()) {
301 m_page.comboBoxChannel->hide();
302 m_page.containerAllChannels->hide();
303 } else {
304 m_page.comboBoxChannel->show();
305 m_page.containerAllChannels->show();
306 const int index = m_page.comboBoxChannel->findData(m_activeChannel);
307 m_page.comboBoxChannel->setCurrentIndex(index);
308 }
309
310 m_page.sliderInputLevels->reset(m_activeLevelsCurve->inputBlackPoint(),
313 m_page.sliderOutputLevels->reset(m_activeLevelsCurve->outputBlackPoint(),
315 {
316 QColor leftColor(Qt::black), rightColor(Qt::white);
317 if (m_page.buttonAllChannelsMode->isChecked() &&
321 const int channelIndex = m_virtualChannels[m_activeChannel].pixelIndex();
323 leftColor = Qt::black;
324 rightColor = channelIndex == 0 ? Qt::blue : (channelIndex == 1 ? Qt::green : Qt::red);
325 } else {
326 leftColor = Qt::white;
327 rightColor = channelIndex == 0 ? Qt::cyan : (channelIndex == 1 ? Qt::magenta : (channelIndex == 2 ? Qt::yellow : Qt::black));
328 rightColor = KoColor(rightColor, KoColorSpaceRegistry::instance()->rgb8())
332 .toQColor();
333 }
334 } else if (m_page.buttonAllChannelsMode->isChecked() &&
337 leftColor = Qt::white;
338 rightColor = Qt::black;
339 }
340 m_page.sliderInputLevels->setHandleColor(0, leftColor);
341 m_page.sliderInputLevels->setHandleColor(1, KisPaintingTweaks::blendColors(leftColor, rightColor, 0.5));
342 m_page.sliderInputLevels->setHandleColor(2, rightColor);
343 m_page.sliderOutputLevels->setHandleColor(0, leftColor);
344 m_page.sliderOutputLevels->setHandleColor(1, rightColor);
345 }
346
347 m_page.spinBoxInputBlackPoint->setRange(m_activeChannelMin, m_activeChannelMax);
348 m_page.spinBoxInputWhitePoint->setRange(m_activeChannelMin, m_activeChannelMax);
349 m_page.spinBoxOutputBlackPoint->setRange(m_activeChannelMin, m_activeChannelMax);
350 m_page.spinBoxOutputWhitePoint->setRange(m_activeChannelMin, m_activeChannelMax);
353 m_page.spinBoxInputGamma->setValue(m_activeLevelsCurve->inputGamma());
356
357 if ((m_page.buttonLightnessMode->isChecked() ||
360
361 m_page.buttonAutoLevels->setEnabled(true);
362
365 m_page.buttonAutoLevels->setEnabled(true);
366 } else {
367 m_page.buttonAutoLevels->setEnabled(false);
368 }
369}
qreal outputBlackPoint() const
Get the output black point.
qreal inputBlackPoint() const
Get the input black point.
qreal inputGamma() const
Get the gamma value.
qreal inputWhitePoint() const
Get the input white point.
qreal outputWhitePoint() const
Get the output white point.
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
QColor blendColors(const QColor &c1, const QColor &c2, qreal r1)

References VirtualChannelInfo::ALL_COLORS, KisPaintingTweaks::blendColors(), CMYKAColorModelID, KoColorSpace::colorModelId(), KoColor::convertedTo(), deNormalizeValue(), KoColorConversionTransformation::Empty, KisLevelsCurve::inputBlackPoint(), KisLevelsCurve::inputGamma(), KisLevelsCurve::inputWhitePoint(), KoColorSpaceRegistry::instance(), KoColorConversionTransformation::IntentSaturation, VirtualChannelInfo::LIGHTNESS, m_activeChannel, m_activeChannelMax, m_activeChannelMin, m_activeLevelsCurve, m_channelsHistogram, m_colorSpace, m_lightnessHistogram, m_page, m_virtualChannels, KisLevelsCurve::outputBlackPoint(), KisLevelsCurve::outputWhitePoint(), VirtualChannelInfo::REAL, RGBAColorModelID, and KoColor::toQColor().

Member Data Documentation

◆ m_activeChannel

int KisLevelsConfigWidget::m_activeChannel
private

Definition at line 75 of file KisLevelsConfigWidget.h.

◆ m_activeChannelMax

int KisLevelsConfigWidget::m_activeChannelMax
private

Definition at line 76 of file KisLevelsConfigWidget.h.

◆ m_activeChannelMin

int KisLevelsConfigWidget::m_activeChannelMin
private

Definition at line 76 of file KisLevelsConfigWidget.h.

◆ m_activeLevelsCurve

KisLevelsCurve* KisLevelsConfigWidget::m_activeLevelsCurve
private

Definition at line 79 of file KisLevelsConfigWidget.h.

◆ m_autoLevelsWidget

KisAutoLevelsWidget* KisLevelsConfigWidget::m_autoLevelsWidget
private

Definition at line 82 of file KisLevelsConfigWidget.h.

◆ m_channelsHistogram

QScopedPointer<KisHistogram> KisLevelsConfigWidget::m_channelsHistogram
private

Definition at line 80 of file KisLevelsConfigWidget.h.

◆ m_colorSpace

const KoColorSpace* KisLevelsConfigWidget::m_colorSpace
private

Definition at line 71 of file KisLevelsConfigWidget.h.

◆ m_dev

KisPaintDeviceSP KisLevelsConfigWidget::m_dev
private

Definition at line 70 of file KisLevelsConfigWidget.h.

◆ m_levelsCurves

QVector<KisLevelsCurve> KisLevelsConfigWidget::m_levelsCurves
private

Definition at line 77 of file KisLevelsConfigWidget.h.

◆ m_lightnessHistogram

QScopedPointer<KisHistogram> KisLevelsConfigWidget::m_lightnessHistogram
private

Definition at line 81 of file KisLevelsConfigWidget.h.

◆ m_lightnessLevelsCurve

KisLevelsCurve KisLevelsConfigWidget::m_lightnessLevelsCurve
private

Definition at line 78 of file KisLevelsConfigWidget.h.

◆ m_lightnessMinMaxRanges

QPair<int, int> KisLevelsConfigWidget::m_lightnessMinMaxRanges
private

Definition at line 74 of file KisLevelsConfigWidget.h.

◆ m_page

Ui::LevelsConfigWidget KisLevelsConfigWidget::m_page
private

Definition at line 69 of file KisLevelsConfigWidget.h.

◆ m_virtualChannels

QVector<VirtualChannelInfo> KisLevelsConfigWidget::m_virtualChannels
private

Definition at line 72 of file KisLevelsConfigWidget.h.

◆ m_virtualChannelsMinMaxRanges

QVector<QPair<int, int> > KisLevelsConfigWidget::m_virtualChannelsMinMaxRanges
private

Definition at line 73 of file KisLevelsConfigWidget.h.


The documentation for this class was generated from the following files: