| 176 | } |
| 177 | |
| 178 | void ClientCompThresholdFader::paintEvent(QPaintEvent*) |
| 179 | { |
| 180 | QPainter p(this); |
| 181 | p.setRenderHint(QPainter::Antialiasing, false); |
| 182 | p.setRenderHint(QPainter::TextAntialiasing, true); |
| 183 | |
| 184 | // Strip vertical bounds — carve between the THRESH label and the |
| 185 | // numeric value label. |
| 186 | const int topLabelH = 16; |
| 187 | const int botLabelH = 14; |
| 188 | const int stripTop = topLabelH + kStripTopPad; |
| 189 | const int stripBot = height() - botLabelH - kStripBottomPad; |
| 190 | m_stripTop = stripTop; |
| 191 | m_stripH = std::max(1, stripBot - stripTop); |
| 192 | |
| 193 | const int barLeft = kLabelColW + kGap + kHandleOverhang; |
| 194 | const QRect barR(barLeft, stripTop, kBarW, m_stripH); |
| 195 | |
| 196 | p.fillRect(barR, AetherSDR::ThemeManager::instance().color("color.background.0")); |
| 197 | |
| 198 | // Level fill — same green→amber→red gradient as the output fader so |
| 199 | // the metering vocabulary is consistent across the app. |
| 200 | const float peakNorm = std::clamp( |
| 201 | (m_smoothedPeakDb - kMeterMinDb) / (kMeterMaxDb - kMeterMinDb), |
| 202 | 0.0f, 1.0f); |
| 203 | const int fillH = static_cast<int>(peakNorm * m_stripH); |
| 204 | if (fillH > 0) { |
| 205 | const QRect fill(barR.x(), barR.y() + m_stripH - fillH, |
| 206 | kBarW, fillH); |
| 207 | QLinearGradient grad(0, barR.y() + m_stripH, 0, barR.y()); |
| 208 | grad.setColorAt(0.0, AetherSDR::ThemeManager::instance().color("color.accent.success")); |
| 209 | grad.setColorAt(0.55, AetherSDR::ThemeManager::instance().color("color.accent.success")); |
| 210 | grad.setColorAt(0.80, AetherSDR::ThemeManager::instance().color("color.accent.warning")); |
| 211 | grad.setColorAt(0.95, AetherSDR::ThemeManager::instance().color("color.accent.danger")); |
| 212 | grad.setColorAt(1.0, AetherSDR::ThemeManager::instance().color("color.accent.danger")); |
| 213 | p.fillRect(fill, grad); |
| 214 | } |
| 215 | |
| 216 | p.setPen(QPen(AetherSDR::ThemeManager::instance().color("color.background.1"), 1)); |
| 217 | p.setBrush(Qt::NoBrush); |
| 218 | p.drawRect(barR.adjusted(0, 0, -1, -1)); |
| 219 | |
| 220 | // dB scale on the left. |
| 221 | QFont f = p.font(); |
| 222 | f.setPixelSize(9); |
| 223 | p.setFont(f); |
| 224 | const QFontMetrics fm(f); |
| 225 | const int textRight = kLabelColW - 2; |
| 226 | |
| 227 | struct Tick { float db; const char* label; }; |
| 228 | static constexpr Tick kTicks[] = { |
| 229 | { 0.0f, "0" }, |
| 230 | { -12.0f, "-12" }, |
| 231 | { -24.0f, "-24" }, |
| 232 | { -36.0f, "-36" }, |
| 233 | { -48.0f, "-48" }, |
| 234 | }; |
| 235 | for (const auto& t : kTicks) { |
nothing calls this directly
no test coverage detected