162 lines
4.1 KiB
C++
162 lines
4.1 KiB
C++
#include "stfslider.h"
|
|
#include <cmath>
|
|
#include <QPainter>
|
|
#include <QPaintEvent>
|
|
#include <QPainterPath>
|
|
#include <QToolTip>
|
|
|
|
static float clamp(float x)
|
|
{
|
|
return std::min(std::max(x, 0.0f), 1.0f);
|
|
}
|
|
|
|
STFSlider::STFSlider(QWidget *parent) : QWidget(parent)
|
|
{
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
|
setMinimumWidth(100);
|
|
setMinimumHeight(15);
|
|
setMaximumHeight(15);
|
|
setMouseTracking(true);
|
|
m_blackPoint = 0;
|
|
m_midPoint = 0.5;
|
|
m_whitePoint = 1;
|
|
m_grabbed = -1;
|
|
m_fineTune = false;
|
|
setToolTip(tr("Press Shift for fine tuning"));
|
|
}
|
|
|
|
float STFSlider::blackPoint() const
|
|
{
|
|
return m_blackPoint;
|
|
}
|
|
|
|
float STFSlider::midPoint() const
|
|
{
|
|
return m_midPoint;
|
|
}
|
|
|
|
float STFSlider::whitePoint() const
|
|
{
|
|
return m_whitePoint;
|
|
}
|
|
|
|
void STFSlider::setMTFParams(float low, float mid, float high)
|
|
{
|
|
m_blackPoint = clamp(low);
|
|
m_midPoint = clamp(mid);
|
|
m_whitePoint = clamp(high);
|
|
update();
|
|
}
|
|
|
|
void STFSlider::paintEvent(QPaintEvent *event)
|
|
{
|
|
QPainter painter(this);
|
|
QRect rect = event->rect();
|
|
qreal w = rect.width() - 1;
|
|
qreal h = rect.height();
|
|
QLinearGradient gradient(rect.topLeft(), rect.topRight());
|
|
gradient.setColorAt(0, Qt::black);
|
|
for(int i=1; i<=32; i++)
|
|
{
|
|
qreal p = i/32.0f;
|
|
qreal c = std::pow(p, 1.0/2.2)*255;
|
|
gradient.setColorAt(p, QColor(c, c, c));
|
|
}
|
|
|
|
QPainterPath tick(QPointF(0, 0));
|
|
tick.lineTo(0, h - 5);
|
|
tick.lineTo(-5, h);
|
|
tick.lineTo(5, h);
|
|
tick.lineTo(0, h - 5);
|
|
|
|
painter.setBrush(gradient);
|
|
painter.setPen(Qt::NoPen);
|
|
painter.drawRect(rect);
|
|
|
|
auto drawTick = [&](qreal p)
|
|
{
|
|
painter.setPen(p < 0.4 ? Qt::white : Qt::black);
|
|
painter.resetTransform();
|
|
painter.translate(w*p, 0);
|
|
painter.drawPath(tick);
|
|
};
|
|
|
|
painter.setBrush(Qt::NoBrush);
|
|
drawTick(m_blackPoint);
|
|
drawTick(m_blackPoint + (m_whitePoint - m_blackPoint) * m_midPoint);
|
|
drawTick(m_whitePoint);
|
|
}
|
|
|
|
void STFSlider::mouseMoveEvent(QMouseEvent *event)
|
|
{
|
|
if(std::abs(m_blackPoint*width() - event->x()) < 5 ||
|
|
std::abs((m_blackPoint + (m_whitePoint - m_blackPoint) * m_midPoint)*width() - event->x()) < 5 ||
|
|
std::abs(m_whitePoint*width() - event->x()) < 5)
|
|
setCursor(Qt::SplitHCursor);
|
|
else
|
|
unsetCursor();
|
|
|
|
qreal x = (qreal)event->x()/width();
|
|
if(event->modifiers() & Qt::ShiftModifier && !m_fineTune)
|
|
{
|
|
m_fineTune = true;
|
|
m_fineTuneX = x;
|
|
}
|
|
if(!(event->modifiers() & Qt::ShiftModifier) && m_fineTune)
|
|
m_fineTune = false;
|
|
|
|
if(m_fineTune)
|
|
{
|
|
x = m_fineTuneX + (x - m_fineTuneX) * 0.2;
|
|
}
|
|
|
|
switch(m_grabbed)
|
|
{
|
|
case 0:
|
|
m_blackPoint = clamp(x);
|
|
m_whitePoint = std::max(m_whitePoint, m_blackPoint);
|
|
QToolTip::showText(event->globalPos(), QString::number(m_blackPoint), this);
|
|
break;
|
|
case 1:
|
|
m_midPoint = (x - m_blackPoint) / (m_whitePoint - m_blackPoint);
|
|
m_midPoint = clamp(m_midPoint);
|
|
QToolTip::showText(event->globalPos(), QString::number(m_midPoint), this);
|
|
break;
|
|
case 2:
|
|
m_whitePoint = clamp(x);
|
|
m_blackPoint = std::min(m_blackPoint, m_whitePoint);
|
|
QToolTip::showText(event->globalPos(), QString::number(m_whitePoint), this);
|
|
break;
|
|
}
|
|
if(m_grabbed >= 0)
|
|
{
|
|
emit paramChanged(m_blackPoint, midPoint(), m_whitePoint);
|
|
update();
|
|
}
|
|
}
|
|
|
|
void STFSlider::mousePressEvent(QMouseEvent *event)
|
|
{
|
|
if(event->modifiers() & Qt::ShiftModifier)
|
|
{
|
|
m_fineTune = true;
|
|
m_fineTuneX = (qreal)event->x()/width();
|
|
}
|
|
|
|
if(std::abs((m_blackPoint + (m_whitePoint - m_blackPoint) * m_midPoint)*width() - event->x()) < 5)
|
|
m_grabbed = 1;
|
|
else if(std::abs(m_blackPoint*width() - event->x()) < 5)
|
|
m_grabbed = 0;
|
|
else if(std::abs(m_whitePoint*width() - event->x()) < 5)
|
|
m_grabbed = 2;
|
|
else
|
|
m_grabbed = -1;
|
|
}
|
|
|
|
void STFSlider::mouseReleaseEvent(QMouseEvent *)
|
|
{
|
|
m_grabbed = -1;
|
|
m_fineTune = false;
|
|
emit paramChanged(m_blackPoint, midPoint(), m_whitePoint);
|
|
}
|