19883929bSAndrew Lindesay /* 266ee6532SAndrew Lindesay * Copyright 2020-2024, Andrew Lindesay <apl@lindesay.co.nz>. 39883929bSAndrew Lindesay * All rights reserved. Distributed under the terms of the MIT License. 49883929bSAndrew Lindesay */ 59883929bSAndrew Lindesay 69883929bSAndrew Lindesay #include <View.h> 79883929bSAndrew Lindesay 89883929bSAndrew Lindesay 99883929bSAndrew Lindesay #include "HaikuDepotConstants.h" 10*c3cad236SAndrew Lindesay #include "Logger.h" 119883929bSAndrew Lindesay #include "RatingUtils.h" 1266ee6532SAndrew Lindesay #include "SharedIcons.h" 139883929bSAndrew Lindesay 149883929bSAndrew Lindesay 15*c3cad236SAndrew Lindesay RatingStarsMetrics::RatingStarsMetrics(BSize starSize) 16*c3cad236SAndrew Lindesay : 17*c3cad236SAndrew Lindesay fStarSize(starSize) 18*c3cad236SAndrew Lindesay { 19*c3cad236SAndrew Lindesay } 20*c3cad236SAndrew Lindesay 21*c3cad236SAndrew Lindesay 22*c3cad236SAndrew Lindesay const BSize 23*c3cad236SAndrew Lindesay RatingStarsMetrics::StarSize() const 24*c3cad236SAndrew Lindesay { 25*c3cad236SAndrew Lindesay return fStarSize; 26*c3cad236SAndrew Lindesay } 27*c3cad236SAndrew Lindesay 28*c3cad236SAndrew Lindesay 29*c3cad236SAndrew Lindesay float 30*c3cad236SAndrew Lindesay RatingStarsMetrics::SpacingBetweenStars() const 31*c3cad236SAndrew Lindesay { 32*c3cad236SAndrew Lindesay return 2.0 * fStarSize.Width() / 16.0; 33*c3cad236SAndrew Lindesay } 34*c3cad236SAndrew Lindesay 35*c3cad236SAndrew Lindesay 36*c3cad236SAndrew Lindesay const BPoint 37*c3cad236SAndrew Lindesay RatingStarsMetrics::LocationOfStarAtIndex(int index) const 38*c3cad236SAndrew Lindesay { 39*c3cad236SAndrew Lindesay float indexf = static_cast<float>(index); 40*c3cad236SAndrew Lindesay return BPoint(indexf * (fStarSize.Width() + SpacingBetweenStars()), 0.0); 41*c3cad236SAndrew Lindesay } 42*c3cad236SAndrew Lindesay 43*c3cad236SAndrew Lindesay 44*c3cad236SAndrew Lindesay const BSize 45*c3cad236SAndrew Lindesay RatingStarsMetrics::Size() const 46*c3cad236SAndrew Lindesay { 47*c3cad236SAndrew Lindesay return BSize((fStarSize.Width() * 5) + (SpacingBetweenStars() * 4), fStarSize.Height()); 48*c3cad236SAndrew Lindesay } 49*c3cad236SAndrew Lindesay 50*c3cad236SAndrew Lindesay 519883929bSAndrew Lindesay /*static*/ void 529883929bSAndrew Lindesay RatingUtils::Draw(BView* target, BPoint at, float value) 539883929bSAndrew Lindesay { 549883929bSAndrew Lindesay const BBitmap* star; 559883929bSAndrew Lindesay 569883929bSAndrew Lindesay if (value < RATING_MIN) 5766ee6532SAndrew Lindesay star = SharedIcons::IconStarGrey16Scaled()->Bitmap(); 589883929bSAndrew Lindesay else 5966ee6532SAndrew Lindesay star = SharedIcons::IconStarBlue16Scaled()->Bitmap(); 609883929bSAndrew Lindesay 619883929bSAndrew Lindesay if (star == NULL) { 629883929bSAndrew Lindesay debugger("no star icon found in application resources."); 639883929bSAndrew Lindesay return; 649883929bSAndrew Lindesay } 659883929bSAndrew Lindesay 669883929bSAndrew Lindesay Draw(target, at, value, star); 679883929bSAndrew Lindesay } 689883929bSAndrew Lindesay 699883929bSAndrew Lindesay 709883929bSAndrew Lindesay /*static*/ void 719883929bSAndrew Lindesay RatingUtils::Draw(BView* target, BPoint at, float value, 729883929bSAndrew Lindesay const BBitmap* star) 739883929bSAndrew Lindesay { 749883929bSAndrew Lindesay if (star == NULL) { 75*c3cad236SAndrew Lindesay HDFATAL("no star icon found in application resources."); 769883929bSAndrew Lindesay return; 779883929bSAndrew Lindesay } 789883929bSAndrew Lindesay 79*c3cad236SAndrew Lindesay RatingStarsMetrics metrics(star->Bounds().Size()); 80*c3cad236SAndrew Lindesay BRect rect(at, metrics.Size()); 81*c3cad236SAndrew Lindesay 82*c3cad236SAndrew Lindesay target->FillRect(rect, B_SOLID_LOW); 83*c3cad236SAndrew Lindesay // a rectangle covering the whole area of the stars 84*c3cad236SAndrew Lindesay 859883929bSAndrew Lindesay target->SetDrawingMode(B_OP_OVER); 869883929bSAndrew Lindesay 87*c3cad236SAndrew Lindesay for (int i = 0; i < 5; i++) 88*c3cad236SAndrew Lindesay target->DrawBitmap(star, rect.LeftTop() + metrics.LocationOfStarAtIndex(i)); 899883929bSAndrew Lindesay 909883929bSAndrew Lindesay if (value >= RATING_MIN && value < 5.0f) { 919883929bSAndrew Lindesay target->SetDrawingMode(B_OP_OVER); 92*c3cad236SAndrew Lindesay BRect shadeOverRect = rect; 93*c3cad236SAndrew Lindesay shadeOverRect.left = ceilf(rect.right - (1.0 - (value / 5.0f)) * rect.Width()); 949883929bSAndrew Lindesay 959883929bSAndrew Lindesay rgb_color color = target->LowColor(); 969883929bSAndrew Lindesay color.alpha = 190; 979883929bSAndrew Lindesay target->SetHighColor(color); 989883929bSAndrew Lindesay 999883929bSAndrew Lindesay target->SetDrawingMode(B_OP_ALPHA); 100*c3cad236SAndrew Lindesay target->FillRect(shadeOverRect, B_SOLID_HIGH); 1019883929bSAndrew Lindesay } 1029883929bSAndrew Lindesay }