1 /*
2 * Copyright 2020-2024, Andrew Lindesay <apl@lindesay.co.nz>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6 #include <View.h>
7
8
9 #include "HaikuDepotConstants.h"
10 #include "Logger.h"
11 #include "RatingUtils.h"
12 #include "SharedIcons.h"
13
14
RatingStarsMetrics(BSize starSize)15 RatingStarsMetrics::RatingStarsMetrics(BSize starSize)
16 :
17 fStarSize(starSize)
18 {
19 }
20
21
22 const BSize
StarSize() const23 RatingStarsMetrics::StarSize() const
24 {
25 return fStarSize;
26 }
27
28
29 float
SpacingBetweenStars() const30 RatingStarsMetrics::SpacingBetweenStars() const
31 {
32 return 2.0 * fStarSize.Width() / 16.0;
33 }
34
35
36 const BPoint
LocationOfStarAtIndex(int index) const37 RatingStarsMetrics::LocationOfStarAtIndex(int index) const
38 {
39 float indexf = static_cast<float>(index);
40 return BPoint(indexf * (fStarSize.Width() + SpacingBetweenStars()), 0.0);
41 }
42
43
44 const BSize
Size() const45 RatingStarsMetrics::Size() const
46 {
47 return BSize((fStarSize.Width() * 5) + (SpacingBetweenStars() * 4), fStarSize.Height());
48 }
49
50
51 /*static*/ void
Draw(BView * target,BPoint at,float value)52 RatingUtils::Draw(BView* target, BPoint at, float value)
53 {
54 const BBitmap* star;
55
56 if (value < RATING_MIN)
57 star = SharedIcons::IconStarGrey16Scaled()->Bitmap();
58 else
59 star = SharedIcons::IconStarBlue16Scaled()->Bitmap();
60
61 if (star == NULL) {
62 debugger("no star icon found in application resources.");
63 return;
64 }
65
66 Draw(target, at, value, star);
67 }
68
69
70 /*static*/ void
Draw(BView * target,BPoint at,float value,const BBitmap * star)71 RatingUtils::Draw(BView* target, BPoint at, float value,
72 const BBitmap* star)
73 {
74 if (star == NULL) {
75 HDFATAL("no star icon found in application resources.");
76 return;
77 }
78
79 RatingStarsMetrics metrics(star->Bounds().Size());
80 BRect rect(at, metrics.Size());
81
82 target->FillRect(rect, B_SOLID_LOW);
83 // a rectangle covering the whole area of the stars
84
85 target->SetDrawingMode(B_OP_OVER);
86
87 for (int i = 0; i < 5; i++)
88 target->DrawBitmap(star, rect.LeftTop() + metrics.LocationOfStarAtIndex(i));
89
90 if (value >= RATING_MIN && value < 5.0f) {
91 target->SetDrawingMode(B_OP_OVER);
92 BRect shadeOverRect = rect;
93 shadeOverRect.left = ceilf(rect.right - (1.0 - (value / 5.0f)) * rect.Width());
94
95 rgb_color color = target->LowColor();
96 color.alpha = 190;
97 target->SetHighColor(color);
98
99 target->SetDrawingMode(B_OP_ALPHA);
100 target->FillRect(shadeOverRect, B_SOLID_HIGH);
101 }
102 }
103
104
105 /*! With the `userRatingInfo` provided, does it make sense for the application
106 to attempt to download the user ratings? If it looks like there are none
107 then it's making no sense and if it has already downloaded some then it
108 also does not make any sense.
109 */
110 /*static*/ bool
ShouldTryPopulateUserRatings(UserRatingInfoRef userRatingInfo)111 RatingUtils::ShouldTryPopulateUserRatings(UserRatingInfoRef userRatingInfo)
112 {
113 if (!userRatingInfo.IsSet())
114 return true;
115
116 UserRatingSummaryRef summary = userRatingInfo->Summary();
117
118 if (!summary.IsSet())
119 return true;
120
121 if (summary->RatingCount() == 0)
122 return false;
123
124 return !userRatingInfo->UserRatingsPopulated();
125 }
126