124 lines
3.4 KiB
C++
124 lines
3.4 KiB
C++
#include "BarRow.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include <QHBoxLayout>
|
|
#include <QLabel>
|
|
#include <QPainter>
|
|
#include <QPaintEvent>
|
|
#include <QVBoxLayout>
|
|
|
|
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<int>(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);
|
|
}
|