xref: /haiku/src/apps/haikudepot/util/RatingUtils.cpp (revision 4b3c808edaaf626e7ee6cb0ee9d21dc96b173ee6)
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