From 344fae26f2d84b147ac3633f4852f76d8a2c9a48 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 29 Dec 2024 14:10:02 +0100 Subject: [PATCH] Draw fader ticks Draw fader ticks in case the model is a linear one. This means that for now they should only be painted for the mixer faders but not for the faders of the Compressor, Delay, etc. Extract the computation of the scaled ratio between the maximum model dB value and the minimum supported fader dB value into the new private method `computeScaledRatio`. This is necessary because it is needed to paint the fader knob at the correct position (using the knob bottom as the reference) and to paint the fader ticks at the correct position (using the knob center). Introduce the private method `paintFaderTicks` which paints the fader ticks. Note: to paint some non-evenly spaced fader ticks replace the `for` expression in `paintFaderTicks` with something like the following: ``` for (auto & i : {6.f, 0.f, -6.f, -12.f, -24.f, -36.f, -48.f, -60.f, -72.f, -84.f, -96.f, -108.f, -120.f}) ``` --- include/Fader.h | 11 +++++++++++ src/gui/widgets/Fader.cpp | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/include/Fader.h b/include/Fader.h index 00a2c5546..e43a6a561 100644 --- a/include/Fader.h +++ b/include/Fader.h @@ -118,10 +118,21 @@ private: void paintEvent(QPaintEvent* ev) override; void paintLevels(QPaintEvent* ev, QPainter& painter, bool linear = false); + void paintFaderTicks(QPainter& painter); int calculateKnobPosYFromModel() const; void setVolumeByLocalPixelValue(int y); + // Computes the scaled ratio between the maximum dB value supported by the model and the minimum + // dB value that's supported by the fader from the given actual dB value. + // If the provided input value lies inside the aforementioned interval then the result will be + // a value between 0 (value == minimum value) and 1 (value == maximum model value). + // If you look at the graphical representation of the fader then 0 represents a point at the bottom + // of the fader and 1 a point at the top of the fader. + // The ratio is scaled by an internal exponent which is an implementation detail that cannot be + // changed for now. + float computeScaledRatio(float dBValue) const; + void setPeak(float fPeak, float& targetPeak, float& persistentPeak, QElapsedTimer& lastPeakTimer); void updateTextFloat(); diff --git a/src/gui/widgets/Fader.cpp b/src/gui/widgets/Fader.cpp index b5a1f0709..422e60b9f 100644 --- a/src/gui/widgets/Fader.cpp +++ b/src/gui/widgets/Fader.cpp @@ -322,18 +322,16 @@ int Fader::calculateKnobPosYFromModel() const } else { - auto const maxDb = ampToDbfs(maxV); - // Make sure that we do not get values less that the minimum fader dbFS // for the calculations that will follow. auto const actualDb = std::max(m_faderMinDb, ampToDbfs(value)); - auto const ratio = (actualDb - m_faderMinDb) / (maxDb - m_faderMinDb); + const auto scaledRatio = computeScaledRatio(actualDb); // This returns results between: // * m_knob.height() for a ratio of 1 // * height() for a ratio of 0 - return height() - (height() - m_knob.height()) * std::pow(ratio, c_dBScalingExponent); + return height() - (height() - m_knob.height()) * scaledRatio; } } else @@ -409,6 +407,15 @@ void Fader::setVolumeByLocalPixelValue(int y) } } +float Fader::computeScaledRatio(float dBValue) const +{ + const auto maxDb = ampToDbfs(model()->maxValue()); + + const auto ratio = (dBValue - m_faderMinDb) / (maxDb - m_faderMinDb); + + return std::pow(ratio, c_dBScalingExponent); +} + /// /// Set peak value (0.0 .. 1.0) @@ -501,6 +508,11 @@ void Fader::paintEvent(QPaintEvent* ev) // Draw the levels with peaks paintLevels(ev, painter, !m_levelsDisplayedInDBFS); + if (modelIsLinear()) + { + paintFaderTicks(painter); + } + // Draw the knob painter.drawPixmap((width() - m_knob.width()) / 2, calculateKnobPosYFromModel() - m_knob.height(), m_knob); } @@ -658,4 +670,22 @@ void Fader::paintLevels(QPaintEvent* ev, QPainter& painter, bool linear) painter.restore(); } +void Fader::paintFaderTicks(QPainter& painter) +{ + painter.save(); + + painter.setPen(QColor(255, 255, 255, 128)); + + for (float i = 6.f; i >= -120.f; i-= 6.f) + { + const auto scaledRatio = computeScaledRatio(i); + const auto maxHeight = height() - (height() - m_knob.height()) * scaledRatio - (m_knob.height() / 2); + + painter.drawLine(QPointF(0, maxHeight), QPointF(1, maxHeight)); + painter.drawLine(QPointF(width() - 1, maxHeight), QPointF(width(), maxHeight)); + } + + painter.restore(); +} + } // namespace lmms::gui