ratingwidget: Properly bind the ratings values

RatingPainter::RatingForPos should return a value in 0-1. But if the
passed position was outside of the widget's draw rectangle, a value
outside of that range could be returned.
This commit is contained in:
Jim Broadus 2021-03-31 21:24:43 -07:00 committed by John Maguire
parent 86d782cb6a
commit eb1b84b281
2 changed files with 13 additions and 7 deletions

View File

@ -34,14 +34,14 @@ RatingPainter::RatingPainter() {
QIcon star_off = IconLoader::Load("star-off", IconLoader::Other);
QPixmap off(star_off.pixmap(star_off.availableSizes().last()));
// Generate the 10 states, better to do it now than on the fly
for (int i = 0; i < kStarCount * 2 + 1; ++i) {
// Generate the 11 states, better to do it now than on the fly
for (int i = 0; i < kStarStates; ++i) {
const float rating = float(i) / 2.0;
// Clear the pixmap
stars_[i] = QPixmap(kStarSize * kStarCount, kStarSize);
stars_[i].fill(Qt::transparent);
QPainter p(&stars_[i]);
star_maps_[i] = QPixmap(kStarSize * kStarCount, kStarSize);
star_maps_[i].fill(Qt::transparent);
QPainter p(&star_maps_[i]);
// Draw the stars
int x = 0;
@ -79,6 +79,10 @@ double RatingPainter::RatingForPos(const QPoint& pos, const QRect& rect) {
const QRect contents = Contents(rect);
const double raw = double(pos.x() - contents.left()) / contents.width();
// Check if the position was to the right or left of the rectangle.
if (raw < 0) return 0;
if (raw > 1) return 1;
// Round to the nearest 0.1
return double(int(raw * kStarCount * 2 + 0.5)) / (kStarCount * 2);
}
@ -93,7 +97,7 @@ void RatingPainter::Paint(QPainter* painter, const QRect& rect,
// Draw the stars
const int star = qBound(0, int(rating * 2.0 + 0.5), kStarCount * 2);
painter->drawPixmap(QRect(pos, size), stars_[star],
painter->drawPixmap(QRect(pos, size), star_maps_[star],
QRect(QPoint(0, 0), size));
}

View File

@ -26,6 +26,7 @@ class RatingPainter {
RatingPainter();
static const int kStarCount = 5;
static const int kStarStates = kStarCount * 2 + 1;
static const int kStarSize = 16;
static QRect Contents(const QRect& rect);
static double RatingForPos(const QPoint& pos, const QRect& rect);
@ -33,7 +34,8 @@ class RatingPainter {
void Paint(QPainter* painter, const QRect& rect, float rating) const;
private:
QPixmap stars_[kStarCount * 2 + 1];
// Pixmap for 0 to kStarCount stars in 1/2 star increments
QPixmap star_maps_[kStarStates];
};
class RatingWidget : public QWidget {