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

This is a input levels slider that has a gamma handle. The handles are constrained so that the black point handle can not pass the white point handle and vice-versa. More...

#include <KisLevelsSlider.h>

+ Inheritance diagram for KisInputLevelsSliderWithGamma:

Public Slots

void reset (qreal newBlackPoint, qreal newWhitePoint) override
 
void reset (qreal newBlackPoint, qreal newWhitePoint, qreal newGamma)
 
void setGamma (qreal newGamma)
 Sets the gamma value.
 
void setHandlePosition (int handleIndex, qreal newPosition) override
 
- Public Slots inherited from KisInputLevelsSlider
virtual void reset (qreal newBlackPoint, qreal newWhitePoint)
 Sometimes you want to set the range to a totally different place, but the new black point can be greater than the old white point so the new black point position will be constrained to the old white position. This function allows to set both values at once to prevent that undesirable effect. Use it when the widget has to show new values, for a different set of levels parameters for example.
 
virtual void setBlackPoint (qreal newBlackPoint)
 Sets the black point.
 
virtual void setWhitePoint (qreal newWhitePoint)
 Sets the white point.
 
- Public Slots inherited from KisLevelsSlider
virtual void setHandleColor (int handleIndex, const QColor &newColor)
 Sets the color associated with the given handle.
 
virtual void setHandlePosition (int handleIndex, qreal newPosition)
 Sets the normalized position of the given handle.
 

Signals

void gammaChanged (qreal newGamma)
 Signal emitted when the gamma value changes.
 
- Signals inherited from KisInputLevelsSlider
void blackPointChanged (qreal newBlackPoint)
 Signal emitted when the black point changes.
 
void whitePointChanged (qreal newWhitePoint)
 Signal emitted when the white point changes.
 
- Signals inherited from KisLevelsSlider
void handleColorChanged (int handleIndex, const QColor &color)
 Signal emitted when the color associated with a handle changes.
 
void handlePositionChanged (int handleIndex, qreal position)
 Signal emitted when the position of a handle changes.
 

Public Member Functions

qreal gamma () const
 Get the gamma value.
 
 KisInputLevelsSliderWithGamma (QWidget *parent=nullptr)
 
 ~KisInputLevelsSliderWithGamma ()
 
- Public Member Functions inherited from KisInputLevelsSlider
qreal blackPoint () const
 Get the normalized black point.
 
 KisInputLevelsSlider (QWidget *parent=nullptr)
 
qreal whitePoint () const
 Get the normalized white point.
 
 ~KisInputLevelsSlider ()
 
- Public Member Functions inherited from KisLevelsSlider
virtual QRect gradientRect () const
 Gets the rect where the gradient will be painted.
 
QColor handleColor (int handleIndex) const
 Gets the color associated with a given handle.
 
qreal handlePosition (int handleIndex) const
 Gets the normalized position of a given handle.
 
 KisLevelsSlider (QWidget *parent)
 
QSize minimumSizeHint () const override
 
QSize sizeHint () const override
 
 ~KisLevelsSlider ()
 

Protected Member Functions

void paintBottomGradientMiddleSection (QImage &gradientImage, const QVector< Handle > &sortedHandles_) override
 This is used to fill the space between the tho handles in the bottom bar of the "gradient". It just paints a linear gradient that goes from black (first handle's color) to white (last handle's color). Derived classes can override this function if they only want to change that area. "gradientImage" is a 256x1px image.
 
- Protected Member Functions inherited from KisInputLevelsSlider
void paintGradient (QPainter &painter, const QRect &rect) override
 Custom gradient painter. This paints two bars in the gradient rect, one on top of the other. The top one shows a simple black to white (more exactly, color of the first handle to color of the last handle) linear gradient. The bottom one shows black (first handle's color) from the right side of the rect to the black point, and white (last handle's color) from the white point to the left side of the rect. In the middle of the two handles, the "paintBottomGradientMiddleSection" is used to fill the bar.
 
- Protected Member Functions inherited from KisLevelsSlider
int closestHandleToPosition (qreal position) const
 Given a normalized position, this function returns the closest handle to that position.
 
int closestHandleToX (int x) const
 Given a widget-relative x position, this function returns the closest handle to that position.
 
void handleIncrementInput (int direction, Qt::KeyboardModifiers modifiers)
 
void keyPressEvent (QKeyEvent *e) override
 
void leaveEvent (QEvent *e) override
 
void mouseMoveEvent (QMouseEvent *e) override
 
void mousePressEvent (QMouseEvent *e) override
 
void paintEvent (QPaintEvent *e) override
 
virtual void paintHandle (QPainter &painter, const QRect &rect, const Handle &handle)
 Override this function to paint custom handles.
 
qreal positionFromX (int x) const
 Given a widget-relative x position in pixels, this function returns the normalized position relative to the gradient rect.
 
QVector< HandlesortedHandles () const
 Regardless the index of a handle, they can be unordered in terms of the position. This returns a sorted vector with the handles that have a smaller position first. If two handles have the same position then the index is used for sorting.
 
void wheelEvent (QWheelEvent *e) override
 
int xFromPosition (qreal position) const
 Given a gradient rect relative position, this function returns the x position in pixels relative to the widget.
 

Private Member Functions

qreal gammaToPosition () const
 
qreal positionToGamma () const
 

Private Attributes

qreal m_gamma
 

Additional Inherited Members

- Protected Attributes inherited from KisLevelsSlider
int m_constrainPositions
 This variable indicates if the handles can have unordered positions. If it is set to true then the user won't be able to move a handle pass another one. If it is set to false then the ser will be able to move the handles freely.
 
QVector< Handlem_handles
 The collection of handles.
 
int m_hoveredHandle
 
int m_selectedHandle
 
- Static Protected Attributes inherited from KisLevelsSlider
static constexpr int handleHeight {11}
 
static constexpr int handleWidth {11}
 
static constexpr qreal minimumSpaceBetweenHandles {0.001}
 
static constexpr qreal normalPositionIncrement {0.01}
 
static constexpr qreal slowPositionIncrement {0.001}
 

Detailed Description

This is a input levels slider that has a gamma handle. The handles are constrained so that the black point handle can not pass the white point handle and vice-versa.

Definition at line 220 of file KisLevelsSlider.h.

Constructor & Destructor Documentation

◆ KisInputLevelsSliderWithGamma()

KisInputLevelsSliderWithGamma::KisInputLevelsSliderWithGamma ( QWidget * parent = nullptr)

Definition at line 454 of file KisLevelsSlider.cpp.

455 : KisInputLevelsSlider(parent)
456 , m_gamma(1.0)
457{
458 m_handles.last().index = 2;
459 m_handles.insert(1, {1, 0.5, Qt::gray});
460}
KisInputLevelsSlider(QWidget *parent=nullptr)
QVector< Handle > m_handles
The collection of handles.

References KisLevelsSlider::m_handles.

◆ ~KisInputLevelsSliderWithGamma()

KisInputLevelsSliderWithGamma::~KisInputLevelsSliderWithGamma ( )

Definition at line 462 of file KisLevelsSlider.cpp.

463{}

Member Function Documentation

◆ gamma()

qreal KisInputLevelsSliderWithGamma::gamma ( ) const

Get the gamma value.

Definition at line 465 of file KisLevelsSlider.cpp.

466{
467 return m_gamma;
468}

References m_gamma.

◆ gammaChanged

void KisInputLevelsSliderWithGamma::gammaChanged ( qreal newGamma)
signal

Signal emitted when the gamma value changes.

◆ gammaToPosition()

qreal KisInputLevelsSliderWithGamma::gammaToPosition ( ) const
private

Definition at line 550 of file KisLevelsSlider.cpp.

551{
552 qreal relativePosition;
553 const qreal log1_2 = std::log(0.5);
554 // the function would be "relativePosition = exp(gamma * ln(1/2)" but since
555 // we want to limit the gamma from 0.1 to 10 we map the gamma
556 // in a way such that "exp(max_gamma * ln(1/2)) = 1" and
557 // "exp(min_gamma * ln(1/2)) = 0"
558 if (m_gamma > 1.0) {
559 const qreal mappedPosition = std::exp(10.0 * log1_2);
560 relativePosition = (std::exp(m_gamma * log1_2) - mappedPosition) / (1.0 - mappedPosition * 2.0);
561 } else {
562 const qreal mappedPosition = std::exp(0.1 * log1_2);
563 relativePosition = (std::exp(m_gamma * log1_2) + mappedPosition - 1.0) / (mappedPosition * 2.0 - 1.0);
564 }
565 return blackPoint() + relativePosition * (whitePoint() - blackPoint());
566}
qreal whitePoint() const
Get the normalized white point.
qreal blackPoint() const
Get the normalized black point.

References KisInputLevelsSlider::blackPoint(), m_gamma, and KisInputLevelsSlider::whitePoint().

◆ paintBottomGradientMiddleSection()

void KisInputLevelsSliderWithGamma::paintBottomGradientMiddleSection ( QImage & gradientImage,
const QVector< Handle > & sortedHandles_ )
overrideprotectedvirtual

This is used to fill the space between the tho handles in the bottom bar of the "gradient". It just paints a linear gradient that goes from black (first handle's color) to white (last handle's color). Derived classes can override this function if they only want to change that area. "gradientImage" is a 256x1px image.

Reimplemented from KisInputLevelsSlider.

Definition at line 526 of file KisLevelsSlider.cpp.

527{
528 if (m_handles.size() < 2) {
529 return;
530 }
531 if (m_handles.size() < 3) {
532 KisInputLevelsSlider::paintBottomGradientMiddleSection(gradientImage, sortedHandles_);
533 return;
534 }
535
536 const qreal inverseGamma = 1.0 / m_gamma;
537 const int startPos = static_cast<int>(qRound(sortedHandles_.first().position * static_cast<qreal>(gradientImage.width() - 1)));
538 const int endPos = static_cast<int>(qRound(sortedHandles_.last().position * static_cast<qreal>(gradientImage.width() - 1))) + 1;
539 QRgb *pixel = reinterpret_cast<QRgb*>(gradientImage.bits()) + startPos;
540 for (int x = startPos; x < endPos; ++x, ++pixel) {
541 const qreal t = static_cast<qreal>(x - startPos) / static_cast<qreal>(endPos - startPos);
543 sortedHandles_.last().color,
544 sortedHandles_.first().color,
545 std::pow(t, inverseGamma)
546 ).rgba();
547 }
548}
virtual void paintBottomGradientMiddleSection(QImage &gradientImage, const QVector< Handle > &sortedHandles_)
This is used to fill the space between the tho handles in the bottom bar of the "gradient"....
unsigned int QRgb
QColor blendColors(const QColor &c1, const QColor &c2, qreal r1)

References KisPaintingTweaks::blendColors(), m_gamma, KisLevelsSlider::m_handles, and KisInputLevelsSlider::paintBottomGradientMiddleSection().

◆ positionToGamma()

qreal KisInputLevelsSliderWithGamma::positionToGamma ( ) const
private

Definition at line 568 of file KisLevelsSlider.cpp.

569{
570 const qreal relativePosition = (handlePosition(1) - blackPoint()) / (whitePoint() - blackPoint());
571 const qreal log1_2 = std::log(0.5);
572 // the function would be "gamma = ln(relativePosition) / ln(1/2)" but since
573 // we want to limit the gamma from 0.1 to 10 we map the relative position
574 // in a way such that "ln(min_relativePosition) / ln(1/2) = 10" and
575 // "ln(max_relativePosition) / ln(1/2) = 0.1"
576 if (relativePosition < 0.5) {
577 const qreal mappedPosition = std::exp(10.0 * log1_2);
578 return std::log(mappedPosition + relativePosition - relativePosition * mappedPosition * 2.0) / log1_2;
579 } else {
580 const qreal mappedPosition = std::exp(0.1 * log1_2);
581 return std::log(1 - (mappedPosition + relativePosition) + relativePosition * mappedPosition * 2.0) / log1_2;
582 }
583}
qreal handlePosition(int handleIndex) const
Gets the normalized position of a given handle.

References KisInputLevelsSlider::blackPoint(), KisLevelsSlider::handlePosition(), and KisInputLevelsSlider::whitePoint().

◆ reset [1/2]

void KisInputLevelsSliderWithGamma::reset ( qreal newBlackPoint,
qreal newWhitePoint )
overrideslot
See also
KisInputLevelsSlider::reset

Definition at line 515 of file KisLevelsSlider.cpp.

516{
517 KisInputLevelsSlider::reset(newBlackPoint, newWhitePoint);
518}
virtual void reset(qreal newBlackPoint, qreal newWhitePoint)
Sometimes you want to set the range to a totally different place, but the new black point can be grea...

References KisInputLevelsSlider::reset().

◆ reset [2/2]

void KisInputLevelsSliderWithGamma::reset ( qreal newBlackPoint,
qreal newWhitePoint,
qreal newGamma )
slot
See also
KisInputLevelsSlider::reset

Definition at line 520 of file KisLevelsSlider.cpp.

521{
522 reset(newBlackPoint, newWhitePoint);
523 setGamma(newGamma);
524}
void setGamma(qreal newGamma)
Sets the gamma value.
void reset(qreal newBlackPoint, qreal newWhitePoint) override

References reset(), and setGamma().

◆ setGamma

void KisInputLevelsSliderWithGamma::setGamma ( qreal newGamma)
slot

Sets the gamma value.

Definition at line 502 of file KisLevelsSlider.cpp.

503{
504 newGamma = qBound(0.1, newGamma, 10.0);
505 if (newGamma == m_gamma) {
506 return;
507 }
508 m_gamma = newGamma;
509 m_handles[1].position = gammaToPosition();
510 update();
511 Q_EMIT gammaChanged(m_gamma);
512 Q_EMIT handlePositionChanged(1, m_handles[1].position);
513}
void gammaChanged(qreal newGamma)
Signal emitted when the gamma value changes.
void handlePositionChanged(int handleIndex, qreal position)
Signal emitted when the position of a handle changes.
bool update(QSpinBox *spinBox)

References gammaChanged(), gammaToPosition(), KisLevelsSlider::handlePositionChanged(), m_gamma, and KisLevelsSlider::m_handles.

◆ setHandlePosition

void KisInputLevelsSliderWithGamma::setHandlePosition ( int handleIndex,
qreal newPosition )
overrideslot

Definition at line 470 of file KisLevelsSlider.cpp.

471{
472 Q_ASSERT(handleIndex >= 0 && handleIndex < m_handles.size());
473
474 if (handleIndex == 1) {
475 newPosition = qBound(m_handles.first().position, newPosition, m_handles.last().position);
476 if (newPosition == m_handles[1].position) {
477 return;
478 }
479 m_handles[1].position = newPosition;
481 update();
482 Q_EMIT handlePositionChanged(1, newPosition);
483 Q_EMIT gammaChanged(m_gamma);
484 } else {
485 if (handleIndex == m_handles.first().index) {
486 newPosition = qBound(0.0, newPosition, m_handles.last().position - minimumSpaceBetweenHandles);
487 } else if (handleIndex == m_handles.last().index) {
488 newPosition = qBound(m_handles.first().position + minimumSpaceBetweenHandles, newPosition, 1.0);
489 }
490 if (newPosition == m_handles[handleIndex].position) {
491 return;
492 }
493 m_handles[handleIndex].position = newPosition;
494 m_handles[1].position = gammaToPosition();
495 update();
496 Q_EMIT handlePositionChanged(handleIndex, newPosition);
497 Q_EMIT handlePositionChanged(1, newPosition);
498 }
499
500}
static constexpr qreal minimumSpaceBetweenHandles

References gammaChanged(), gammaToPosition(), KisLevelsSlider::handlePositionChanged(), m_gamma, KisLevelsSlider::m_handles, KisLevelsSlider::minimumSpaceBetweenHandles, and positionToGamma().

Member Data Documentation

◆ m_gamma

qreal KisInputLevelsSliderWithGamma::m_gamma
private

Definition at line 258 of file KisLevelsSlider.h.


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