#include "BarRow.h" #include #include #include #include #include #include namespace { // Height and corner radius of the fill bar, in device-independent pixels. const int kBarHeightPx = 6; const qreal kBarRadiusPx = 3.0; // Opacity of the unfilled track, over the card's background. const int kTrackAlpha = 60; } // namespace // The bar itself. Painted rather than assembled from a QProgressBar, because all it // needs is a rounded track with a rounded fill and a style sheet cannot be relied on to // leave a progress bar's groove and chunk alone across styles. class BarRow::Bar : public QWidget { public: explicit Bar(QWidget* parent) : QWidget(parent) , m_fraction(0.0) { setFixedHeight(kBarHeightPx); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); } void setFraction(double fraction) { m_fraction = std::max(0.0, std::min(1.0, fraction)); update(); } void setFillColor(const QColor& color) { m_fillColor = color; update(); } protected: void paintEvent(QPaintEvent* /*event*/) override { // The active group is asked for by name rather than taken from the current one, // which follows the window's focus: the inactive group's highlight is close // enough to the card's background that the bar reads as gone whenever the game // is tabbed away from or a modal dialog holds focus -- exactly when a player // watching a build finish is most likely to be looking at it. const QColor fill = m_fillColor.isValid() ? m_fillColor : palette().color(QPalette::Active, QPalette::Highlight); QColor track = fill; track.setAlpha(kTrackAlpha); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(Qt::NoPen); painter.setBrush(track); painter.drawRoundedRect(rect(), kBarRadiusPx, kBarRadiusPx); if (m_fraction > 0.0) { QRect filled = rect(); filled.setWidth(static_cast(filled.width() * m_fraction)); painter.setBrush(fill); painter.drawRoundedRect(filled, kBarRadiusPx, kBarRadiusPx); } } private: double m_fraction; QColor m_fillColor; }; BarRow::BarRow(const QString& caption, QWidget* parent) : QWidget(parent) { QVBoxLayout* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(2); QWidget* captionRow = new QWidget(this); QHBoxLayout* captionLayout = new QHBoxLayout(captionRow); captionLayout->setContentsMargins(0, 0, 0, 0); captionLayout->setSpacing(8); m_captionLabel = new QLabel(caption, captionRow); m_captionLabel->setVisible(!caption.isEmpty()); m_valueLabel = new QLabel(captionRow); m_valueLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); captionLayout->addWidget(m_captionLabel); captionLayout->addStretch(1); captionLayout->addWidget(m_valueLabel); m_bar = new Bar(this); layout->addWidget(captionRow); layout->addWidget(m_bar); } void BarRow::setValue(double fraction, const QString& valueText) { m_bar->setFraction(fraction); m_valueLabel->setText(valueText); } void BarRow::setFillColor(const QColor& color) { m_bar->setFillColor(color); }