| 235 | } |
| 236 | |
| 237 | void ClientCompKnob::paintEvent(QPaintEvent*) |
| 238 | { |
| 239 | QPainter p(this); |
| 240 | p.setRenderHint(QPainter::Antialiasing, true); |
| 241 | |
| 242 | const int w = width(); |
| 243 | const int h = height(); |
| 244 | // Center-label mode reclaims the 12-px label row above the ring. |
| 245 | // The ring uses almost all remaining height — the 270° arc sweep |
| 246 | // (225° → -45°) leaves a 90° gap at the bottom (4:30 → 7:30), |
| 247 | // which is where the value readout lives. Reserving a separate |
| 248 | // "row" below the ring creates a visible gap; overlapping the |
| 249 | // empty arc sector keeps the readout snug against the knob. |
| 250 | const int topRow = m_centerLabel ? 0 : 12; |
| 251 | const int bottomRow = 4; |
| 252 | const int diameter = std::min(w - 4, h - topRow - bottomRow); |
| 253 | const QRectF ring((w - diameter) * 0.5f, |
| 254 | static_cast<float>(topRow), |
| 255 | diameter, diameter); |
| 256 | |
| 257 | // Label — above the ring in classic mode, centred inside the |
| 258 | // ring in center-label mode. Centred text is rendered AFTER |
| 259 | // the arc + pointer so it reads on top cleanly. |
| 260 | QFont labelFont = p.font(); |
| 261 | labelFont.setPixelSize(9); |
| 262 | labelFont.setBold(true); |
| 263 | if (!m_centerLabel) { |
| 264 | // Shrink-to-fit: longer labels ("Threshold", "Release") on |
| 265 | // narrow knobs would otherwise truncate with "..." — scale |
| 266 | // the font down in 1-px steps until the rendered width fits |
| 267 | // the widget, floor at 7 px. |
| 268 | int pixelSize = 9; |
| 269 | QFontMetrics fm(labelFont); |
| 270 | const float maxWidth = std::max(8.0f, static_cast<float>(w) - 2.0f); |
| 271 | while (fm.horizontalAdvance(m_label) > maxWidth && pixelSize > 7) { |
| 272 | --pixelSize; |
| 273 | labelFont.setPixelSize(pixelSize); |
| 274 | fm = QFontMetrics(labelFont); |
| 275 | } |
| 276 | p.setFont(labelFont); |
| 277 | p.setPen(kLabelColor(this)); |
| 278 | p.drawText(QRectF(0, 0, w, 12), Qt::AlignCenter, m_label); |
| 279 | } |
| 280 | |
| 281 | // Background ring. |
| 282 | const qreal thick = std::max(2.0, diameter * 0.10); |
| 283 | QPen bgPen(kRingBg(this), thick); |
| 284 | bgPen.setCapStyle(Qt::FlatCap); |
| 285 | p.setPen(bgPen); |
| 286 | p.drawArc(ring.adjusted(thick * 0.5, thick * 0.5, |
| 287 | -thick * 0.5, -thick * 0.5), |
| 288 | static_cast<int>(kArcStartDeg * 16.0f), |
| 289 | static_cast<int>(kArcSpanDeg * 16.0f)); |
| 290 | |
| 291 | // Value arc. |
| 292 | QPen arcPen(kRingArc(this), thick); |
| 293 | arcPen.setCapStyle(Qt::FlatCap); |
| 294 | p.setPen(arcPen); |
nothing calls this directly
no test coverage detected