xref: /haiku/src/apps/haikudepot/util/RatingUtils.cpp (revision 344ded80d400028c8f561b4b876257b94c12db4a)
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 
15 RatingStarsMetrics::RatingStarsMetrics(BSize starSize)
16 	:
17 	fStarSize(starSize)
18 {
19 }
20 
21 
22 const BSize
23 RatingStarsMetrics::StarSize() const
24 {
25 	return fStarSize;
26 }
27 
28 
29 float
30 RatingStarsMetrics::SpacingBetweenStars() const
31 {
32 	return 2.0 * fStarSize.Width() / 16.0;
33 }
34 
35 
36 const BPoint
37 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
45 RatingStarsMetrics::Size() const
46 {
47 	return BSize((fStarSize.Width() * 5) + (SpacingBetweenStars() * 4), fStarSize.Height());
48 }
49 
50 
51 /*static*/ void
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
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
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