Mercurial > hg > svgui
comparison widgets/LevelPanWidget.cpp @ 1306:5db672d6de4f
Better rendering for widget cells
author | Chris Cannam |
---|---|
date | Mon, 25 Jun 2018 15:29:47 +0100 |
parents | 21342513c252 |
children | 5af5c611f4cb |
comparison
equal
deleted
inserted
replaced
1305:21342513c252 | 1306:5db672d6de4f |
---|---|
390 double adj = thinLineWidth(rect)/2; | 390 double adj = thinLineWidth(rect)/2; |
391 return clr.adjusted(-adj, -adj, adj, adj); | 391 return clr.adjusted(-adj, -adj, adj, adj); |
392 } | 392 } |
393 | 393 |
394 QColor | 394 QColor |
395 LevelPanWidget::notchToColour(int notch) const | 395 LevelPanWidget::cellToColour(int cell) const |
396 { | 396 { |
397 if (notch < 3) return Qt::black; | 397 if (cell < 1) return Qt::black; |
398 if (notch < 5) return QColor(80, 0, 0); | 398 if (cell < 2) return QColor(80, 0, 0); |
399 if (notch < 7) return QColor(160, 0, 0); | 399 if (cell < 3) return QColor(160, 0, 0); |
400 if (notch < 9) return QColor(255, 0, 0); | 400 if (cell < 4) return QColor(255, 0, 0); |
401 return QColor(255, 255, 0); | 401 return QColor(255, 255, 0); |
402 } | 402 } |
403 | 403 |
404 void | 404 void |
405 LevelPanWidget::renderTo(QPaintDevice *dev, QRectF rect, bool asIfEditable) const | 405 LevelPanWidget::renderTo(QPaintDevice *dev, QRectF rect, bool asIfEditable) const |
406 { | 406 { |
407 QPainter paint(dev); | 407 QPainter paint(dev); |
408 | 408 |
409 paint.setRenderHint(QPainter::Antialiasing, true); | 409 paint.setRenderHint(QPainter::Antialiasing, true); |
410 | |
411 QPen pen; | |
412 | 410 |
413 double thin = thinLineWidth(rect); | 411 double thin = thinLineWidth(rect); |
414 double radius = cornerRadius(rect); | 412 double radius = cornerRadius(rect); |
415 | 413 |
416 QColor columnBackground = QColor(180, 180, 180); | 414 QColor columnBackground = QColor(180, 180, 180); |
417 paint.setPen(Qt::NoPen); | 415 |
418 paint.setBrush(columnBackground); | 416 bool monitoring = (m_monitorLeft > 0.f || m_monitorRight > 0.f); |
417 | |
418 QPen pen; | |
419 if (isEnabled()) { | |
420 pen.setColor(Qt::black); | |
421 } else { | |
422 pen.setColor(Qt::darkGray); | |
423 } | |
424 pen.setWidthF(thin); | |
425 pen.setCapStyle(Qt::FlatCap); | |
426 pen.setJoinStyle(Qt::MiterJoin); | |
419 | 427 |
420 for (int pan = -maxPan; pan <= maxPan; ++pan) { | 428 for (int pan = -maxPan; pan <= maxPan; ++pan) { |
429 | |
430 paint.setPen(Qt::NoPen); | |
431 paint.setBrush(columnBackground); | |
432 | |
421 QRectF top = cellOutlineRect(rect, m_maxNotch/2 - 1, pan); | 433 QRectF top = cellOutlineRect(rect, m_maxNotch/2 - 1, pan); |
422 QRectF bottom = cellOutlineRect(rect, 0, pan); | 434 QRectF bottom = cellOutlineRect(rect, 0, pan); |
423 paint.drawRoundedRect(QRectF(top.x(), | 435 paint.drawRoundedRect(QRectF(top.x(), |
424 top.y(), | 436 top.y(), |
425 top.width(), | 437 top.width(), |
426 bottom.y() + bottom.height() - top.y()), | 438 bottom.y() + bottom.height() - top.y()), |
427 radius, radius); | 439 radius, radius); |
428 } | 440 |
429 | 441 if (!asIfEditable && m_includeMute && m_notch == 0) { |
430 bool monitoring = (m_monitorLeft > 0.f || m_monitorRight > 0.f); | 442 // We will instead be drawing a single big X for mute, |
431 | 443 // after this loop |
432 if (isEnabled()) { | 444 continue; |
433 pen.setColor(Qt::black); | 445 } |
434 } else { | 446 |
435 pen.setColor(Qt::darkGray); | 447 if (!monitoring && m_pan != pan) { |
448 continue; | |
449 } | |
450 | |
451 int monitorNotch = 0; | |
452 if (monitoring) { | |
453 float rprop = float(pan - (-maxPan)) / float(maxPan * 2); | |
454 float lprop = float(maxPan - pan) / float(maxPan * 2); | |
455 float monitorLevel = | |
456 lprop * m_monitorLeft * m_monitorLeft + | |
457 rprop * m_monitorRight * m_monitorRight; | |
458 monitorNotch = audioLevelToNotch(monitorLevel); | |
459 } | |
460 | |
461 int firstCell = 0; | |
462 int lastCell = m_maxNotch / 2 - 1; | |
463 | |
464 for (int cell = firstCell; cell <= lastCell; ++cell) { | |
465 | |
466 QRectF clr = cellLightRect(rect, cell, pan); | |
467 | |
468 if (m_includeMute && m_pan == pan && m_notch == 0) { | |
469 // X for mute in the bottom cell | |
470 paint.setPen(pen); | |
471 paint.drawLine(clr.topLeft(), clr.bottomRight()); | |
472 paint.drawLine(clr.bottomLeft(), clr.topRight()); | |
473 break; | |
474 } | |
475 | |
476 const int none = 0, half = 1, full = 2; | |
477 | |
478 int fill = none; | |
479 | |
480 int outline = none; | |
481 if (m_pan == pan && m_notch > cell * 2 + 1) { | |
482 outline = full; | |
483 } else if (m_pan == pan && m_notch == cell * 2 + 1) { | |
484 outline = half; | |
485 } | |
486 | |
487 if (monitoring) { | |
488 if (monitorNotch > cell * 2 + 1) { | |
489 fill = full; | |
490 } else if (monitorNotch == cell * 2 + 1) { | |
491 fill = half; | |
492 } | |
493 } else { | |
494 if (isEnabled()) { | |
495 fill = outline; | |
496 } | |
497 } | |
498 | |
499 // If one of {fill, outline} is "full" and the other is | |
500 // "half", then we draw the "half" one first (because we | |
501 // need to erase half of it) | |
502 | |
503 if (fill == half || outline == half) { | |
504 if (fill == half) { | |
505 paint.setBrush(cellToColour(cell)); | |
506 } else { | |
507 paint.setBrush(Qt::NoBrush); | |
508 } | |
509 if (outline == half) { | |
510 paint.setPen(pen); | |
511 } else { | |
512 paint.setPen(Qt::NoPen); | |
513 } | |
514 | |
515 paint.drawRoundedRect(clr, radius, radius); | |
516 | |
517 paint.setBrush(columnBackground); | |
518 | |
519 if (cell == lastCell) { | |
520 QPen bgpen(pen); | |
521 bgpen.setColor(columnBackground); | |
522 paint.setPen(bgpen); | |
523 paint.drawRoundedRect(QRectF(clr.x(), | |
524 clr.y(), | |
525 clr.width(), | |
526 clr.height()/4), | |
527 radius, radius); | |
528 paint.drawRect(QRectF(clr.x(), | |
529 clr.y() + clr.height()/4, | |
530 clr.width(), | |
531 clr.height()/4)); | |
532 } else { | |
533 paint.setPen(Qt::NoPen); | |
534 if (outline == half) { | |
535 clr = cellOutlineRect(rect, cell, pan); | |
536 } | |
537 paint.drawRect(QRectF(clr.x(), | |
538 clr.y() - 0.5, | |
539 clr.width(), | |
540 clr.height()/2)); | |
541 } | |
542 } | |
543 | |
544 if (outline == full || fill == full) { | |
545 | |
546 if (fill == full) { | |
547 paint.setBrush(cellToColour(cell)); | |
548 } else { | |
549 paint.setBrush(Qt::NoBrush); | |
550 } | |
551 if (outline == full) { | |
552 paint.setPen(pen); | |
553 } else { | |
554 paint.setPen(Qt::NoPen); | |
555 } | |
556 | |
557 paint.drawRoundedRect(clr, radius, radius); | |
558 } | |
559 } | |
436 } | 560 } |
437 | 561 |
438 if (!asIfEditable && m_includeMute && m_notch == 0) { | 562 if (!asIfEditable && m_includeMute && m_notch == 0) { |
439 // The X for mute takes up the whole display when we're not | 563 // The X for mute takes up the whole display when we're not |
440 // being rendered in editable style | 564 // being rendered in editable style |
565 pen.setColor(Qt::black); | |
441 pen.setWidthF(thin * 2); | 566 pen.setWidthF(thin * 2); |
442 pen.setCapStyle(Qt::RoundCap); | 567 pen.setCapStyle(Qt::RoundCap); |
443 paint.setPen(pen); | 568 paint.setPen(pen); |
444 paint.drawLine(cellCentre(rect, 0, -maxPan), | 569 paint.drawLine(cellCentre(rect, 0, -maxPan), |
445 cellCentre(rect, m_maxNotch/2 - 1, maxPan)); | 570 cellCentre(rect, m_maxNotch/2 - 1, maxPan)); |
446 paint.drawLine(cellCentre(rect, m_maxNotch/2 - 1, -maxPan), | 571 paint.drawLine(cellCentre(rect, m_maxNotch/2 - 1, -maxPan), |
447 cellCentre(rect, 0, maxPan)); | 572 cellCentre(rect, 0, maxPan)); |
448 } else { | |
449 // the normal case | |
450 | |
451 // pen a bit less thin than in theory, so that we can erase | |
452 // semi-circles later without leaving a faint edge | |
453 pen.setWidthF(thin * 0.8); | |
454 pen.setCapStyle(Qt::FlatCap); | |
455 paint.setPen(pen); | |
456 | |
457 if (m_includeMute && m_notch == 0) { | |
458 QRectF clr = cellLightRect(rect, 0, m_pan); | |
459 paint.drawLine(clr.topLeft(), clr.bottomRight()); | |
460 paint.drawLine(clr.bottomLeft(), clr.topRight()); | |
461 } else { | |
462 for (int notch = 1; notch <= m_notch; notch += 2) { | |
463 if (isEnabled() && !monitoring) { | |
464 paint.setBrush(notchToColour(notch)); | |
465 } else { | |
466 paint.setBrush(Qt::NoBrush); | |
467 } | |
468 QRectF clr = cellLightRect(rect, notch/2, m_pan); | |
469 paint.drawRoundedRect(clr, radius, radius); | |
470 } | |
471 if (m_notch % 2 != 0) { | |
472 QRectF clr = cellOutlineRect(rect, (m_notch-1)/2, m_pan); | |
473 paint.save(); | |
474 paint.setPen(Qt::NoPen); | |
475 paint.setBrush(columnBackground); | |
476 paint.drawRoundedRect(QRectF(clr.x(), | |
477 clr.y(), | |
478 clr.width(), | |
479 clr.height()/4 + thin), | |
480 radius, radius); | |
481 paint.drawRect(QRectF(clr.x(), | |
482 clr.y() + clr.height()/4 - thin, | |
483 clr.width(), | |
484 clr.height()/4 + thin)); | |
485 paint.restore(); | |
486 } | |
487 } | |
488 } | |
489 | |
490 if (monitoring) { | |
491 paint.setPen(Qt::NoPen); | |
492 | |
493 for (int pan = -maxPan; pan <= maxPan; ++pan) { | |
494 float rprop = float(pan - (-maxPan)) / float(maxPan * 2); | |
495 float lprop = float(maxPan - pan) / float(maxPan * 2); | |
496 float audioLevel = | |
497 lprop * m_monitorLeft * m_monitorLeft + | |
498 rprop * m_monitorRight * m_monitorRight; | |
499 int notchHere = audioLevelToNotch(audioLevel); | |
500 | |
501 for (int notch = 1; notch <= notchHere; notch += 2) { | |
502 | |
503 paint.setBrush(notchToColour(notch)); | |
504 QRectF clr = cellLightRect(rect, (notch-1)/2, pan); | |
505 // double adj = thinLineWidth(rect)/2; | |
506 // clr = clr.adjusted(adj, adj, -adj, -adj); | |
507 paint.drawRoundedRect(clr, radius, radius); | |
508 | |
509 if (notch + 2 > notchHere && notchHere % 2 != 0) { | |
510 paint.save(); | |
511 paint.setBrush(columnBackground); | |
512 paint.drawRoundedRect(QRectF(clr.x(), | |
513 clr.y()-0.5, | |
514 clr.width(), | |
515 clr.height()/4 + thin), | |
516 radius, radius); | |
517 paint.drawRect(QRectF(clr.x(), | |
518 clr.y() + clr.height()/4 - thin, | |
519 clr.width(), | |
520 clr.height()/4 + thin)); | |
521 paint.restore(); | |
522 } | |
523 } | |
524 } | |
525 } | 573 } |
526 } | 574 } |
527 | 575 |
528 void | 576 void |
529 LevelPanWidget::paintEvent(QPaintEvent *) | 577 LevelPanWidget::paintEvent(QPaintEvent *) |