mirror of
https://review.haiku-os.org/haiku
synced 2024-11-23 07:18:40 +01:00
HaikuDepot: UI Scaling
Fix aspects of HaikuDepot's UI that do not scale when the font size changes to accommodate a high resolution monitor. Change-Id: I105ebfe5a8f501cd7ffc22822438147ba07382a3 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7844 Reviewed-by: waddlesplash <waddlesplash@gmail.com> Haiku-Format: Haiku-format Bot <no-reply+haikuformatbot@haiku-os.org>
This commit is contained in:
parent
987a1436b3
commit
c3cad23617
@ -89,35 +89,32 @@ IconTarPtrEntryListener::Handle(const TarArchiveHeader& header,
|
||||
fileName.CopyInto(packageName, 5, secondSlashIdx - 5);
|
||||
fileName.CopyInto(leafName, secondSlashIdx + 1,
|
||||
fileName.Length() - (secondSlashIdx + 1));
|
||||
BitmapSize bitmapSize;
|
||||
BitmapSize storedSize;
|
||||
|
||||
if (_LeafNameToBitmapSize(leafName, &bitmapSize) == B_OK) {
|
||||
fPackageIconTarRepository->AddIconTarPtr(packageName, bitmapSize,
|
||||
offset);
|
||||
}
|
||||
if (_LeafNameToBitmapSize(leafName, &storedSize) == B_OK)
|
||||
fPackageIconTarRepository->AddIconTarPtr(packageName, storedSize, offset);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
IconTarPtrEntryListener::_LeafNameToBitmapSize(BString& leafName,
|
||||
BitmapSize* bitmapSize)
|
||||
IconTarPtrEntryListener::_LeafNameToBitmapSize(BString& leafName, BitmapSize* storedSize)
|
||||
{
|
||||
if (leafName == "icon.hvif") {
|
||||
*bitmapSize = BITMAP_SIZE_ANY;
|
||||
*storedSize = BITMAP_SIZE_ANY;
|
||||
return B_OK;
|
||||
}
|
||||
if (leafName == "64.png") {
|
||||
*bitmapSize = BITMAP_SIZE_64;
|
||||
*storedSize = BITMAP_SIZE_64;
|
||||
return B_OK;
|
||||
}
|
||||
if (leafName == "32.png") {
|
||||
*bitmapSize = BITMAP_SIZE_32;
|
||||
*storedSize = BITMAP_SIZE_32;
|
||||
return B_OK;
|
||||
}
|
||||
if (leafName == "16.png") {
|
||||
*bitmapSize = BITMAP_SIZE_16;
|
||||
*storedSize = BITMAP_SIZE_16;
|
||||
return B_OK;
|
||||
}
|
||||
return B_BAD_VALUE;
|
||||
@ -230,11 +227,11 @@ PackageIconTarRepository::_Close()
|
||||
the parsing of the tar headers. It is called from the listener above.
|
||||
*/
|
||||
void
|
||||
PackageIconTarRepository::AddIconTarPtr(const BString& packageName, BitmapSize bitmapSize,
|
||||
PackageIconTarRepository::AddIconTarPtr(const BString& packageName, BitmapSize storedSize,
|
||||
off_t offset)
|
||||
{
|
||||
IconTarPtrRef tarPtrRef = _GetOrCreateIconTarPtr(packageName);
|
||||
tarPtrRef->SetOffset(bitmapSize, offset);
|
||||
tarPtrRef->SetOffset(storedSize, offset);
|
||||
}
|
||||
|
||||
|
||||
@ -263,20 +260,20 @@ PackageIconTarRepository::GetIcon(const BString& pkgName, uint32 size,
|
||||
status_t result = B_OK;
|
||||
off_t iconDataTarOffset = -1;
|
||||
const IconTarPtrRef tarPtrRef = _GetIconTarPtr(pkgName);
|
||||
BitmapSize bitmapSize;
|
||||
BitmapSize storedSize;
|
||||
|
||||
if (tarPtrRef.IsSet()) {
|
||||
bitmapSize = _BestStoredSize(tarPtrRef, size);
|
||||
iconDataTarOffset = tarPtrRef->Offset(bitmapSize);
|
||||
storedSize = _BestStoredSize(tarPtrRef, size);
|
||||
iconDataTarOffset = tarPtrRef->Offset(storedSize);
|
||||
}
|
||||
|
||||
if (iconDataTarOffset >= 0) {
|
||||
HashString key = _ToIconCacheKey(pkgName, bitmapSize);
|
||||
HashString key = _ToIconCacheKey(pkgName, storedSize, size);
|
||||
|
||||
if (fIconCache.ContainsKey(key)) {
|
||||
bitmapHolderRef.SetTo(fIconCache.Get(key).Get());
|
||||
} else {
|
||||
result = _CreateIconFromTarOffset(iconDataTarOffset, bitmapHolderRef);
|
||||
result = _CreateIconFromTarOffset(iconDataTarOffset, storedSize, size, bitmapHolderRef);
|
||||
if (result == B_OK) {
|
||||
HDTRACE("loaded package icon [%s] of size %" B_PRId32, pkgName.String(), size);
|
||||
fIconCache.Put(key, bitmapHolderRef);
|
||||
@ -303,10 +300,9 @@ PackageIconTarRepository::_GetIconTarPtr(const BString& pkgName) const
|
||||
|
||||
|
||||
const char*
|
||||
PackageIconTarRepository::_ToIconCacheKeySuffix(BitmapSize size)
|
||||
PackageIconTarRepository::_ToIconCacheKeyPart(BitmapSize storedSize)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
switch (storedSize) {
|
||||
case BITMAP_SIZE_16:
|
||||
return "16";
|
||||
// note that size 22 is not supported.
|
||||
@ -324,16 +320,19 @@ PackageIconTarRepository::_ToIconCacheKeySuffix(BitmapSize size)
|
||||
|
||||
|
||||
const HashString
|
||||
PackageIconTarRepository::_ToIconCacheKey(const BString& pkgName, BitmapSize size)
|
||||
PackageIconTarRepository::_ToIconCacheKey(const BString& pkgName, BitmapSize storedSize,
|
||||
uint32 size)
|
||||
{
|
||||
return HashString(BString(pkgName) << "__x" << _ToIconCacheKeySuffix(size));
|
||||
return HashString(
|
||||
BString(pkgName) << "__s" << _ToIconCacheKeyPart(storedSize) << "__x" << size);
|
||||
}
|
||||
|
||||
|
||||
/*! This method must only be invoked with the class locked.
|
||||
*/
|
||||
status_t
|
||||
PackageIconTarRepository::_CreateIconFromTarOffset(off_t offset, BitmapHolderRef& bitmapHolderRef)
|
||||
PackageIconTarRepository::_CreateIconFromTarOffset(off_t offset, BitmapSize storedSize, uint32 size,
|
||||
BitmapHolderRef& bitmapHolderRef)
|
||||
{
|
||||
fTarIo->Seek(offset, SEEK_SET);
|
||||
fIconDataBuffer->Seek(0, SEEK_SET);
|
||||
@ -365,17 +364,29 @@ PackageIconTarRepository::_CreateIconFromTarOffset(off_t offset, BitmapHolderRef
|
||||
|
||||
fIconDataBuffer->Seek(0, SEEK_SET);
|
||||
|
||||
if (result == B_OK) {
|
||||
BBitmap* bitmap = BTranslationUtils::GetBitmap(fIconDataBuffer);
|
||||
BBitmap* bitmap = NULL;
|
||||
|
||||
if (bitmap == NULL) {
|
||||
HDERROR("unable to decode data from tar for icon image");
|
||||
result = B_ERROR;
|
||||
if (result == B_OK) {
|
||||
if (BITMAP_SIZE_ANY == storedSize) {
|
||||
bitmap = new BBitmap(BRect(0, 0, size - 1, size - 1), 0, B_RGBA32);
|
||||
result = bitmap->InitCheck();
|
||||
result = BIconUtils::GetVectorIcon(
|
||||
reinterpret_cast<const uint8*>(fIconDataBuffer->Buffer()), header.Length(), bitmap);
|
||||
} else {
|
||||
bitmapHolderRef.SetTo(new(std::nothrow) BitmapHolder(bitmap), true);
|
||||
bitmap = BTranslationUtils::GetBitmap(fIconDataBuffer);
|
||||
|
||||
if (bitmap == NULL) {
|
||||
HDERROR("unable to decode data from tar for icon image");
|
||||
result = B_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != B_OK)
|
||||
delete bitmap;
|
||||
else
|
||||
bitmapHolderRef.SetTo(new(std::nothrow) BitmapHolder(bitmap), true);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -38,15 +38,15 @@ public:
|
||||
private:
|
||||
void _Close();
|
||||
|
||||
const char* _ToIconCacheKeySuffix(BitmapSize size);
|
||||
const HashString _ToIconCacheKey(const BString& pkgName,
|
||||
BitmapSize size);
|
||||
const char* _ToIconCacheKeyPart(BitmapSize size);
|
||||
const HashString _ToIconCacheKey(const BString& pkgName, BitmapSize storedSize,
|
||||
uint32 size);
|
||||
|
||||
IconTarPtrRef _GetOrCreateIconTarPtr(const BString& pkgName);
|
||||
IconTarPtrRef _GetIconTarPtr(const BString& pkgName) const;
|
||||
|
||||
status_t _CreateIconFromTarOffset(off_t offset,
|
||||
BitmapHolderRef& bitmapHolderRef);
|
||||
status_t _CreateIconFromTarOffset(off_t offset, BitmapSize bitmapSize,
|
||||
uint32 size, BitmapHolderRef& bitmapHolderRef);
|
||||
|
||||
status_t _GetDefaultIcon(uint32 size, BitmapHolderRef& bitmapHolderRef);
|
||||
|
||||
|
@ -22,12 +22,12 @@ ScreenshotCoordinate::ScreenshotCoordinate()
|
||||
ScreenshotCoordinate::ScreenshotCoordinate(const BMessage* from)
|
||||
{
|
||||
from->FindString(kCodeKey, &fCode);
|
||||
from->FindUInt16(kWidthKey, &fWidth);
|
||||
from->FindUInt16(kHeightKey, &fHeight);
|
||||
from->FindUInt32(kWidthKey, &fWidth);
|
||||
from->FindUInt32(kHeightKey, &fHeight);
|
||||
}
|
||||
|
||||
|
||||
ScreenshotCoordinate::ScreenshotCoordinate(BString code, uint16 width, uint16 height)
|
||||
ScreenshotCoordinate::ScreenshotCoordinate(BString code, uint32 width, uint32 height)
|
||||
:
|
||||
fCode(code),
|
||||
fWidth(width),
|
||||
@ -48,14 +48,14 @@ ScreenshotCoordinate::Code() const
|
||||
}
|
||||
|
||||
|
||||
uint16
|
||||
uint32
|
||||
ScreenshotCoordinate::Width() const
|
||||
{
|
||||
return fWidth;
|
||||
}
|
||||
|
||||
|
||||
uint16
|
||||
uint32
|
||||
ScreenshotCoordinate::Height() const
|
||||
{
|
||||
return fHeight;
|
||||
@ -80,7 +80,7 @@ const BString
|
||||
ScreenshotCoordinate::Key() const
|
||||
{
|
||||
BString result;
|
||||
result.SetToFormat("%s_%" B_PRIu16 "x%" B_PRIu16 , fCode.String(), fWidth, fHeight);
|
||||
result.SetToFormat("%s_%" B_PRIu32 "x%" B_PRIu32, fCode.String(), fWidth, fHeight);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -99,8 +99,8 @@ ScreenshotCoordinate::Archive(BMessage* into, bool deep) const
|
||||
if (result == B_OK)
|
||||
result = into->AddString(kCodeKey, fCode);
|
||||
if (result == B_OK)
|
||||
result = into->AddUInt16(kWidthKey, fWidth);
|
||||
result = into->AddUInt32(kWidthKey, fWidth);
|
||||
if (result == B_OK)
|
||||
result = into->AddUInt16(kHeightKey, fHeight);
|
||||
result = into->AddUInt32(kHeightKey, fHeight);
|
||||
return result;
|
||||
}
|
||||
|
@ -18,13 +18,13 @@
|
||||
class ScreenshotCoordinate : public BArchivable {
|
||||
public:
|
||||
ScreenshotCoordinate(const BMessage* from);
|
||||
ScreenshotCoordinate(BString code, uint16 width, uint16 height);
|
||||
ScreenshotCoordinate(BString code, uint32 width, uint32 height);
|
||||
ScreenshotCoordinate();
|
||||
virtual ~ScreenshotCoordinate();
|
||||
|
||||
const BString Code() const;
|
||||
uint16 Width() const;
|
||||
uint16 Height() const;
|
||||
uint32 Width() const;
|
||||
uint32 Height() const;
|
||||
|
||||
bool operator==(const ScreenshotCoordinate& other) const;
|
||||
|
||||
@ -36,8 +36,8 @@ public:
|
||||
|
||||
private:
|
||||
BString fCode;
|
||||
uint16 fWidth;
|
||||
uint16 fHeight;
|
||||
uint32 fWidth;
|
||||
uint32 fHeight;
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Catalog.h>
|
||||
#include <ControlLook.h>
|
||||
#include <Font.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <LayoutItem.h>
|
||||
#include <Message.h>
|
||||
#include <ScrollView.h>
|
||||
#include <StringView.h>
|
||||
#include <SpaceLayoutItem.h>
|
||||
|
||||
#include "BitmapView.h"
|
||||
#include "HaikuDepotConstants.h"
|
||||
@ -35,21 +35,148 @@
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "FeaturedPackagesView"
|
||||
|
||||
|
||||
#define HEIGHT_PACKAGE 84.0f
|
||||
#define SIZE_ICON 64.0f
|
||||
#define X_POSITION_RATING 350.0f
|
||||
#define X_POSITION_SUMMARY 500.0f
|
||||
#define WIDTH_RATING 100.0f
|
||||
#define Y_PROPORTION_TITLE 0.35f
|
||||
#define Y_PROPORTION_PUBLISHER 0.60f
|
||||
#define Y_PROPORTION_CHRONOLOGICAL_DATA 0.75f
|
||||
#define PADDING 8.0f
|
||||
|
||||
// If the space for the summary has less than this many "M" characters then the summary will not be
|
||||
// displayed.
|
||||
#define MINIMUM_M_COUNT_SUMMARY 10.0f
|
||||
|
||||
// The title area will be this many times the width of an "M".
|
||||
#define M_COUNT_TITLE 10
|
||||
|
||||
|
||||
// #pragma mark - PackageView
|
||||
|
||||
|
||||
class StackedFeaturesPackageBandMetrics
|
||||
{
|
||||
public:
|
||||
StackedFeaturesPackageBandMetrics(float width, BFont* titleFont, BFont* metadataFont)
|
||||
{
|
||||
float padding = be_control_look->DefaultItemSpacing();
|
||||
BSize iconSize = BControlLook::ComposeIconSize(SIZE_ICON);
|
||||
|
||||
font_height titleFontHeight;
|
||||
font_height metadataFontHeight;
|
||||
titleFont->GetHeight(&titleFontHeight);
|
||||
metadataFont->GetHeight(&metadataFontHeight);
|
||||
|
||||
float totalTitleAndMetadataHeight = titleFontHeight.ascent + titleFontHeight.descent
|
||||
+ titleFontHeight.leading
|
||||
+ metadataFontHeight.leading
|
||||
+ 2.0 * (metadataFontHeight.ascent + metadataFontHeight.descent);
|
||||
|
||||
fHeight = fmaxf(totalTitleAndMetadataHeight, iconSize.Height()) + 2.0 * padding;
|
||||
|
||||
{
|
||||
float iconInset = (fHeight - iconSize.Width()) / 2.0;
|
||||
fIconRect = BRect(padding, iconInset, iconSize.Width() + padding,
|
||||
iconSize.Height() + iconInset);
|
||||
}
|
||||
|
||||
{
|
||||
float titleWidthM = titleFont->StringWidth("M");
|
||||
|
||||
float leftTitlePublisherAndChronologicalInfo = fIconRect.right + padding;
|
||||
float rightTitlePublisherAndChronologicalInfo = fminf(width, fIconRect.Size().Width()
|
||||
+ (2.0 * padding) + (titleWidthM * M_COUNT_TITLE));
|
||||
|
||||
// left, top, right bottom
|
||||
fTitleRect = BRect(leftTitlePublisherAndChronologicalInfo,
|
||||
(fHeight - totalTitleAndMetadataHeight) / 2.0,
|
||||
rightTitlePublisherAndChronologicalInfo,
|
||||
((fHeight - totalTitleAndMetadataHeight) / 2.0)
|
||||
+ titleFontHeight.ascent + titleFontHeight.descent);
|
||||
|
||||
fPublisherRect = BRect(leftTitlePublisherAndChronologicalInfo,
|
||||
fTitleRect.bottom + titleFontHeight.leading,
|
||||
rightTitlePublisherAndChronologicalInfo,
|
||||
fTitleRect.bottom + titleFontHeight.leading
|
||||
+ metadataFontHeight.ascent + metadataFontHeight.descent);
|
||||
|
||||
fChronologicalInfoRect = BRect(leftTitlePublisherAndChronologicalInfo,
|
||||
fPublisherRect.bottom + metadataFontHeight.leading,
|
||||
rightTitlePublisherAndChronologicalInfo,
|
||||
fPublisherRect.bottom + metadataFontHeight.leading
|
||||
+ metadataFontHeight.ascent + metadataFontHeight.descent);
|
||||
}
|
||||
|
||||
// sort out the ratings display
|
||||
|
||||
{
|
||||
BSize ratingStarSize = SharedIcons::IconStarBlue16Scaled()->Bitmap()->Bounds().Size();
|
||||
RatingStarsMetrics ratingStarsMetrics(ratingStarSize);
|
||||
|
||||
fRatingStarsRect = BRect(BPoint(fTitleRect.right + padding,
|
||||
(fHeight - ratingStarsMetrics.Size().Height()) / 2), ratingStarsMetrics.Size());
|
||||
|
||||
if (fRatingStarsRect.right > width)
|
||||
fRatingStarsRect = BRect();
|
||||
else {
|
||||
// Now sort out the position for the summary. This is reckoned as a container
|
||||
// rect because it would be nice to layout the text with newlines and not just a
|
||||
// single line.
|
||||
|
||||
fSummaryContainerRect = BRect(fRatingStarsRect.right + (padding * 2.0), padding,
|
||||
width - padding, fHeight - (padding * 2.0));
|
||||
|
||||
float metadataWidthM = metadataFont->StringWidth("M");
|
||||
|
||||
if (fSummaryContainerRect.Size().Width() < MINIMUM_M_COUNT_SUMMARY * metadataWidthM)
|
||||
fSummaryContainerRect = BRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float Height()
|
||||
{
|
||||
return fHeight;
|
||||
}
|
||||
|
||||
BRect IconRect()
|
||||
{
|
||||
return fIconRect;
|
||||
}
|
||||
|
||||
BRect TitleRect()
|
||||
{
|
||||
return fTitleRect;
|
||||
}
|
||||
|
||||
BRect PublisherRect()
|
||||
{
|
||||
return fPublisherRect;
|
||||
}
|
||||
|
||||
BRect ChronologicalInfoRect()
|
||||
{
|
||||
return fChronologicalInfoRect;
|
||||
}
|
||||
|
||||
BRect RatingStarsRect()
|
||||
{
|
||||
return fRatingStarsRect;
|
||||
}
|
||||
|
||||
BRect SummaryContainerRect()
|
||||
{
|
||||
return fSummaryContainerRect;
|
||||
}
|
||||
|
||||
private:
|
||||
float fHeight;
|
||||
|
||||
BRect fIconRect;
|
||||
BRect fTitleRect;
|
||||
BRect fPublisherRect;
|
||||
BRect fChronologicalInfoRect;
|
||||
|
||||
BRect fRatingStarsRect;
|
||||
|
||||
BRect fSummaryContainerRect;
|
||||
};
|
||||
|
||||
|
||||
class StackedFeaturedPackagesView : public BView {
|
||||
public:
|
||||
StackedFeaturedPackagesView(Model& model)
|
||||
@ -62,6 +189,12 @@ public:
|
||||
fLowestIndexAddedOrRemoved(-1)
|
||||
{
|
||||
SetEventMask(B_POINTER_EVENTS);
|
||||
|
||||
fTitleFont = StackedFeaturedPackagesView::CreateTitleFont();
|
||||
fMetadataFont = StackedFeaturedPackagesView::CreateMetadataFont();
|
||||
fSummaryFont = StackedFeaturedPackagesView::CreateSummaryFont();
|
||||
fBandMetrics = CreateBandMetrics();
|
||||
|
||||
Clear();
|
||||
}
|
||||
|
||||
@ -70,6 +203,10 @@ public:
|
||||
{
|
||||
fPackageListener->SetPackage(PackageInfoRef(NULL));
|
||||
fPackageListener->ReleaseReference();
|
||||
delete fBandMetrics;
|
||||
delete fTitleFont;
|
||||
delete fMetadataFont;
|
||||
delete fSummaryFont;
|
||||
}
|
||||
|
||||
// #pragma mark - message handling and events
|
||||
@ -144,7 +281,7 @@ public:
|
||||
case B_PAGE_DOWN:
|
||||
{
|
||||
BRect bounds = Bounds();
|
||||
float height = fPackages.size() * HEIGHT_PACKAGE;
|
||||
float height = fPackages.size() * fBandMetrics->Height();
|
||||
float maxScrollY = height - bounds.Height();
|
||||
float pageDownScrollY = bounds.top + bounds.Height();
|
||||
ScrollTo(0, fminf(maxScrollY, pageDownScrollY));
|
||||
@ -177,12 +314,10 @@ public:
|
||||
{
|
||||
BView::FrameResized(width, height);
|
||||
|
||||
// because the summary text will wrap, a resize of the frame will
|
||||
// result in all of the summary area needing to be redrawn.
|
||||
delete fBandMetrics;
|
||||
fBandMetrics = CreateBandMetrics();
|
||||
|
||||
BRect rectToInvalidate = Bounds();
|
||||
rectToInvalidate.left = X_POSITION_SUMMARY;
|
||||
Invalidate(rectToInvalidate);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
@ -208,10 +343,46 @@ public:
|
||||
}
|
||||
fPackages.clear();
|
||||
fSelectedIndex = -1;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
static BFont* CreateTitleFont()
|
||||
{
|
||||
BFont* font = new BFont(be_plain_font);
|
||||
font_family family;
|
||||
font_style style;
|
||||
font->SetSize(ceilf(font->Size() * 1.8f));
|
||||
font->GetFamilyAndStyle(&family, &style);
|
||||
font->SetFamilyAndStyle(family, "Bold");
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
static BFont* CreateMetadataFont()
|
||||
{
|
||||
BFont* font = new BFont(be_plain_font);
|
||||
font_family family;
|
||||
font_style style;
|
||||
font->GetFamilyAndStyle(&family, &style);
|
||||
font->SetFamilyAndStyle(family, "Italic");
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
static BFont* CreateSummaryFont()
|
||||
{
|
||||
return new BFont(be_plain_font);
|
||||
}
|
||||
|
||||
|
||||
StackedFeaturesPackageBandMetrics* CreateBandMetrics()
|
||||
{
|
||||
return new StackedFeaturesPackageBandMetrics(Bounds().Width(), fTitleFont, fMetadataFont);
|
||||
}
|
||||
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return fPackages.size() == 0;
|
||||
@ -386,13 +557,11 @@ public:
|
||||
|
||||
void _DrawPackageAtIndex(BRect updateRect, int32 index)
|
||||
{
|
||||
_DrawPackage(updateRect, fPackages[index], index, _YOfIndex(index),
|
||||
index == fSelectedIndex);
|
||||
_DrawPackage(updateRect, fPackages[index], _YOfIndex(index), index == fSelectedIndex);
|
||||
}
|
||||
|
||||
|
||||
void _DrawPackage(BRect updateRect, PackageInfoRef pkg, int index, float y,
|
||||
bool selected)
|
||||
void _DrawPackage(BRect updateRect, PackageInfoRef pkg, float y, bool selected)
|
||||
{
|
||||
if (selected) {
|
||||
SetLowUIColor(B_LIST_SELECTED_BACKGROUND_COLOR);
|
||||
@ -400,152 +569,155 @@ public:
|
||||
} else {
|
||||
SetLowUIColor(B_LIST_BACKGROUND_COLOR);
|
||||
}
|
||||
|
||||
BRect iconRect = fBandMetrics->IconRect();
|
||||
BRect titleRect = fBandMetrics->TitleRect();
|
||||
BRect publisherRect = fBandMetrics->PublisherRect();
|
||||
BRect chronologicalInfoRect = fBandMetrics->ChronologicalInfoRect();
|
||||
BRect ratingStarsRect = fBandMetrics->RatingStarsRect();
|
||||
BRect summaryContainerRect = fBandMetrics->SummaryContainerRect();
|
||||
|
||||
iconRect.OffsetBy(0.0, y);
|
||||
titleRect.OffsetBy(0.0, y);
|
||||
publisherRect.OffsetBy(0.0, y);
|
||||
chronologicalInfoRect.OffsetBy(0.0, y);
|
||||
ratingStarsRect.OffsetBy(0.0, y);
|
||||
summaryContainerRect.OffsetBy(0.0, y);
|
||||
|
||||
// TODO; optimization; the updateRect may only cover some of this?
|
||||
_DrawPackageIcon(updateRect, pkg, y, selected);
|
||||
_DrawPackageTitle(updateRect, pkg, y, selected);
|
||||
_DrawPackagePublisher(updateRect, pkg, y, selected);
|
||||
_DrawPackageCronologicalInfo(updateRect, pkg, y, selected);
|
||||
_DrawPackageRating(updateRect, pkg, y, selected);
|
||||
_DrawPackageSummary(updateRect, pkg, y, selected);
|
||||
_DrawPackageIcon(iconRect, pkg, selected);
|
||||
_DrawPackageTitle(titleRect, pkg, selected);
|
||||
_DrawPackagePublisher(publisherRect, pkg, selected);
|
||||
_DrawPackageChronologicalInfo(chronologicalInfoRect, pkg, selected);
|
||||
_DrawPackageRating(ratingStarsRect, pkg);
|
||||
_DrawPackageSummary(summaryContainerRect, pkg, selected);
|
||||
}
|
||||
|
||||
|
||||
void _DrawPackageIcon(BRect updateRect, PackageInfoRef pkg, float y,
|
||||
bool selected)
|
||||
void _DrawPackageIcon(BRect iconRect, PackageInfoRef pkg, bool selected)
|
||||
{
|
||||
if (!iconRect.IsValid())
|
||||
return;
|
||||
|
||||
BitmapHolderRef icon;
|
||||
status_t iconResult = fModel.GetPackageIconRepository().GetIcon(
|
||||
pkg->Name(), 64, icon);
|
||||
status_t iconResult = fModel.GetPackageIconRepository().GetIcon(pkg->Name(),
|
||||
iconRect.Width(), icon);
|
||||
|
||||
if (iconResult == B_OK) {
|
||||
if (icon.IsSet()) {
|
||||
float inset = (HEIGHT_PACKAGE - SIZE_ICON) / 2.0;
|
||||
BRect targetRect = BRect(inset, y + inset, SIZE_ICON + inset,
|
||||
y + SIZE_ICON + inset);
|
||||
const BBitmap* bitmap = icon->Bitmap();
|
||||
|
||||
if (bitmap != NULL && bitmap->IsValid()) {
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
DrawBitmap(bitmap, bitmap->Bounds(), targetRect,
|
||||
B_FILTER_BITMAP_BILINEAR);
|
||||
DrawBitmap(bitmap, bitmap->Bounds(), iconRect, B_FILTER_BITMAP_BILINEAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _DrawPackageTitle(BRect updateRect, PackageInfoRef pkg, float y,
|
||||
bool selected)
|
||||
void _DrawPackageTitle(BRect textRect, PackageInfoRef pkg, bool selected)
|
||||
{
|
||||
static BFont* sFont = NULL;
|
||||
if (!textRect.IsValid())
|
||||
return;
|
||||
|
||||
if (sFont == NULL) {
|
||||
sFont = new BFont(be_plain_font);
|
||||
GetFont(sFont);
|
||||
font_family family;
|
||||
font_style style;
|
||||
sFont->SetSize(ceilf(sFont->Size() * 1.8f));
|
||||
sFont->GetFamilyAndStyle(&family, &style);
|
||||
sFont->SetFamilyAndStyle(family, "Bold");
|
||||
}
|
||||
const BBitmap* installedIconBitmap = SharedIcons::IconInstalled16Scaled()->Bitmap();
|
||||
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
SetHighUIColor(selected ? B_LIST_SELECTED_ITEM_TEXT_COLOR
|
||||
: B_LIST_ITEM_TEXT_COLOR);
|
||||
SetFont(sFont);
|
||||
BPoint pt(HEIGHT_PACKAGE, y + (HEIGHT_PACKAGE * Y_PROPORTION_TITLE));
|
||||
DrawString(pkg->Title(), pt);
|
||||
SetHighUIColor(selected ? B_LIST_SELECTED_ITEM_TEXT_COLOR : B_LIST_ITEM_TEXT_COLOR);
|
||||
SetFont(fTitleFont);
|
||||
|
||||
font_height fontHeight;
|
||||
fTitleFont->GetHeight(&fontHeight);
|
||||
BPoint pt = textRect.LeftTop() + BPoint(0.0, + fontHeight.ascent);
|
||||
|
||||
BString renderedText = pkg->Title();
|
||||
float installedIconAllowance = installedIconBitmap->Bounds().Width() * 1.5;
|
||||
TruncateString(&renderedText, B_TRUNCATE_END, textRect.Width() - installedIconAllowance);
|
||||
|
||||
DrawString(renderedText, pt);
|
||||
|
||||
if (pkg->State() == ACTIVATED) {
|
||||
const BBitmap* bitmap = SharedIcons::IconInstalled16Scaled()->Bitmap();
|
||||
if (bitmap != NULL && bitmap->IsValid()) {
|
||||
float stringWidth = StringWidth(pkg->Title());
|
||||
float offsetX = pt.x + stringWidth + PADDING;
|
||||
BRect targetRect(offsetX, pt.y - 16,
|
||||
offsetX + 16, pt.y);
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
DrawBitmap(bitmap, bitmap->Bounds(), targetRect,
|
||||
B_FILTER_BITMAP_BILINEAR);
|
||||
}
|
||||
float stringWidth = StringWidth(pkg->Title());
|
||||
BRect iconRect = BRect(
|
||||
BPoint(textRect.left + stringWidth + (installedIconBitmap->Bounds().Width() / 2.0),
|
||||
textRect.top + (textRect.Height() / 2.0)
|
||||
- (installedIconBitmap->Bounds().Height() / 2.0)),
|
||||
installedIconBitmap->Bounds().Size());
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
DrawBitmap(installedIconBitmap, installedIconBitmap->Bounds(), iconRect,
|
||||
B_FILTER_BITMAP_BILINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _DrawPackageGenericTextSlug(BRect updateRect, PackageInfoRef pkg,
|
||||
const BString& text, float y, float yProportion, bool selected)
|
||||
void _DrawPackageGenericTextSlug(BRect textRect, const BString& text, bool selected)
|
||||
{
|
||||
static BFont* sFont = NULL;
|
||||
|
||||
if (sFont == NULL) {
|
||||
sFont = new BFont(be_plain_font);
|
||||
font_family family;
|
||||
font_style style;
|
||||
sFont->SetSize(std::max(9.0f, floorf(sFont->Size() * 0.92f)));
|
||||
sFont->GetFamilyAndStyle(&family, &style);
|
||||
sFont->SetFamilyAndStyle(family, "Italic");
|
||||
}
|
||||
if (!textRect.IsValid())
|
||||
return;
|
||||
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
SetHighUIColor(selected ? B_LIST_SELECTED_ITEM_TEXT_COLOR
|
||||
: B_LIST_ITEM_TEXT_COLOR);
|
||||
SetFont(sFont);
|
||||
SetHighUIColor(selected ? B_LIST_SELECTED_ITEM_TEXT_COLOR : B_LIST_ITEM_TEXT_COLOR);
|
||||
SetFont(fMetadataFont);
|
||||
|
||||
font_height fontHeight;
|
||||
fMetadataFont->GetHeight(&fontHeight);
|
||||
BPoint pt = textRect.LeftTop() + BPoint(0.0, + fontHeight.ascent);
|
||||
|
||||
float maxTextWidth = (X_POSITION_RATING - HEIGHT_PACKAGE) - PADDING;
|
||||
BString renderedText(text);
|
||||
TruncateString(&renderedText, B_TRUNCATE_END, maxTextWidth);
|
||||
TruncateString(&renderedText, B_TRUNCATE_END, textRect.Width());
|
||||
|
||||
DrawString(renderedText, BPoint(HEIGHT_PACKAGE,
|
||||
y + (HEIGHT_PACKAGE * yProportion)));
|
||||
DrawString(renderedText, pt);
|
||||
}
|
||||
|
||||
|
||||
void _DrawPackagePublisher(BRect updateRect, PackageInfoRef pkg, float y,
|
||||
bool selected)
|
||||
void _DrawPackagePublisher(BRect textRect, PackageInfoRef pkg, bool selected)
|
||||
{
|
||||
_DrawPackageGenericTextSlug(updateRect, pkg, pkg->Publisher().Name(), y,
|
||||
Y_PROPORTION_PUBLISHER, selected);
|
||||
_DrawPackageGenericTextSlug(textRect, pkg->Publisher().Name(), selected);
|
||||
}
|
||||
|
||||
|
||||
void _DrawPackageCronologicalInfo(BRect updateRect, PackageInfoRef pkg,
|
||||
float y, bool selected)
|
||||
void _DrawPackageChronologicalInfo(BRect textRect, PackageInfoRef pkg, bool selected)
|
||||
{
|
||||
BString versionCreateTimestampPresentation
|
||||
= LocaleUtils::TimestampToDateString(pkg->VersionCreateTimestamp());
|
||||
_DrawPackageGenericTextSlug(updateRect, pkg,
|
||||
versionCreateTimestampPresentation, y,
|
||||
Y_PROPORTION_CHRONOLOGICAL_DATA, selected);
|
||||
_DrawPackageGenericTextSlug(textRect, versionCreateTimestampPresentation, selected);
|
||||
}
|
||||
|
||||
|
||||
// TODO; show the sample size
|
||||
void _DrawPackageRating(BRect updateRect, PackageInfoRef pkg, float y,
|
||||
bool selected)
|
||||
void _DrawPackageRating(BRect ratingRect, PackageInfoRef pkg)
|
||||
{
|
||||
BPoint at(X_POSITION_RATING,
|
||||
y + (HEIGHT_PACKAGE - SIZE_RATING_STAR) / 2.0f);
|
||||
RatingUtils::Draw(this, at,
|
||||
pkg->CalculateRatingSummary().averageRating);
|
||||
if (!ratingRect.IsValid())
|
||||
return;
|
||||
RatingUtils::Draw(this, ratingRect.LeftTop(), pkg->CalculateRatingSummary().averageRating);
|
||||
}
|
||||
|
||||
|
||||
// TODO; handle multi-line rendering of the text
|
||||
void _DrawPackageSummary(BRect updateRect, PackageInfoRef pkg, float y,
|
||||
bool selected)
|
||||
void _DrawPackageSummary(BRect textRect, PackageInfoRef pkg, bool selected)
|
||||
{
|
||||
BRect bounds = Bounds();
|
||||
if (!textRect.IsValid())
|
||||
return;
|
||||
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
SetHighUIColor(selected ? B_LIST_SELECTED_ITEM_TEXT_COLOR
|
||||
: B_LIST_ITEM_TEXT_COLOR);
|
||||
SetFont(be_plain_font);
|
||||
SetHighUIColor(selected ? B_LIST_SELECTED_ITEM_TEXT_COLOR : B_LIST_ITEM_TEXT_COLOR);
|
||||
SetFont(fSummaryFont);
|
||||
|
||||
font_height fontHeight;
|
||||
fSummaryFont->GetHeight(&fontHeight);
|
||||
|
||||
// The text rect is a container into which later text can be made to flow multi-line. For
|
||||
// now just draw one line of the summary.
|
||||
|
||||
BPoint pt = textRect.LeftTop() + BPoint(0.0,
|
||||
(textRect.Size().Height() / 2.0) - ((fontHeight.ascent + fontHeight.descent) / 2.0)
|
||||
+ fontHeight.ascent);
|
||||
|
||||
float maxTextWidth = bounds.Width() - X_POSITION_SUMMARY - PADDING;
|
||||
BString summary(pkg->ShortDescription());
|
||||
TruncateString(&summary, B_TRUNCATE_END, maxTextWidth);
|
||||
TruncateString(&summary, B_TRUNCATE_END, textRect.Width());
|
||||
|
||||
DrawString(summary, BPoint(X_POSITION_SUMMARY,
|
||||
y + (HEIGHT_PACKAGE * 0.5)));
|
||||
DrawString(summary, pt);
|
||||
}
|
||||
|
||||
|
||||
@ -563,13 +735,11 @@ public:
|
||||
{
|
||||
if (!_IsIndexEntirelyVisible(index)) {
|
||||
BRect bounds = Bounds();
|
||||
int32 indexOfCentreVisible = _IndexOfY(
|
||||
bounds.top + bounds.Height() / 2);
|
||||
int32 indexOfCentreVisible = _IndexOfY(bounds.top + bounds.Height() / 2);
|
||||
if (index < indexOfCentreVisible)
|
||||
ScrollTo(0, _YOfIndex(index));
|
||||
else {
|
||||
float scrollPointY = (_YOfIndex(index) + HEIGHT_PACKAGE)
|
||||
- bounds.Height();
|
||||
float scrollPointY = (_YOfIndex(index) + fBandMetrics->Height()) - bounds.Height();
|
||||
ScrollTo(0, scrollPointY);
|
||||
}
|
||||
}
|
||||
@ -613,13 +783,13 @@ public:
|
||||
|
||||
BRect _RectOfY(float y) const
|
||||
{
|
||||
return BRect(0, y, Bounds().Width(), y + HEIGHT_PACKAGE);
|
||||
return BRect(0, y, Bounds().Width(), y + fBandMetrics->Height());
|
||||
}
|
||||
|
||||
|
||||
float _YOfIndex(int32 i) const
|
||||
{
|
||||
return i * HEIGHT_PACKAGE;
|
||||
return i * fBandMetrics->Height();
|
||||
}
|
||||
|
||||
|
||||
@ -632,7 +802,7 @@ public:
|
||||
{
|
||||
if (fPackages.empty())
|
||||
return -1;
|
||||
int32 i = static_cast<int32>(y / HEIGHT_PACKAGE);
|
||||
int32 i = static_cast<int32>(y / fBandMetrics->Height());
|
||||
if (i < 0 || i >= static_cast<int32>(fPackages.size()))
|
||||
return -1;
|
||||
return i;
|
||||
@ -649,7 +819,7 @@ public:
|
||||
{
|
||||
if (fPackages.empty())
|
||||
return -1;
|
||||
int32 i = static_cast<int32>(y / HEIGHT_PACKAGE);
|
||||
int32 i = static_cast<int32>(y / fBandMetrics->Height());
|
||||
if (i < 0)
|
||||
return 0;
|
||||
return std::min(i, (int32) (fPackages.size() - 1));
|
||||
@ -658,7 +828,8 @@ public:
|
||||
|
||||
virtual BSize PreferredSize()
|
||||
{
|
||||
return BSize(B_SIZE_UNLIMITED, HEIGHT_PACKAGE * fPackages.size());
|
||||
return BSize(B_SIZE_UNLIMITED,
|
||||
fBandMetrics->Height() * static_cast<float>(fPackages.size()));
|
||||
}
|
||||
|
||||
|
||||
@ -670,6 +841,12 @@ private:
|
||||
OnePackageMessagePackageListener*
|
||||
fPackageListener;
|
||||
int32 fLowestIndexAddedOrRemoved;
|
||||
StackedFeaturesPackageBandMetrics*
|
||||
fBandMetrics;
|
||||
|
||||
BFont* fTitleFont;
|
||||
BFont* fMetadataFont;
|
||||
BFont* fSummaryFont;
|
||||
};
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <CardLayout.h>
|
||||
#include <Catalog.h>
|
||||
#include <ColumnListView.h>
|
||||
#include <ControlLook.h>
|
||||
#include <Font.h>
|
||||
#include <GridView.h>
|
||||
#include <LayoutBuilder.h>
|
||||
@ -64,7 +65,7 @@ enum {
|
||||
|
||||
|
||||
static const float kContentTint = (B_NO_TINT + B_LIGHTEN_1_TINT) / 2.0f;
|
||||
static const uint16 kScreenshotSize = 320;
|
||||
static const uint32 kScreenshotSize = 320;
|
||||
|
||||
|
||||
class RatingsScrollView : public GeneralContentScrollView {
|
||||
@ -361,8 +362,9 @@ public:
|
||||
void SetPackage(const PackageInfoRef package)
|
||||
{
|
||||
BitmapHolderRef bitmapHolderRef;
|
||||
status_t iconResult = fPackageIconRepository.GetIcon(
|
||||
package->Name(), 32, bitmapHolderRef);
|
||||
BSize iconSize = BControlLook::ComposeIconSize(32.0);
|
||||
status_t iconResult = fPackageIconRepository.GetIcon(package->Name(), iconSize.Width() + 1,
|
||||
bitmapHolderRef);
|
||||
|
||||
if (iconResult == B_OK)
|
||||
fIconView->SetBitmap(bitmapHolderRef);
|
||||
@ -1402,7 +1404,13 @@ PackageInfoView::_ScreenshotThumbCoordinate(const PackageInfoRef& package)
|
||||
return ScreenshotCoordinate();
|
||||
if (package->CountScreenshotInfos() == 0)
|
||||
return ScreenshotCoordinate();
|
||||
return ScreenshotCoordinate(package->ScreenshotInfoAtIndex(0)->Code(), kScreenshotSize, kScreenshotSize);
|
||||
|
||||
uint32 screenshotSizeScaled
|
||||
= MAX(static_cast<uint32>(BControlLook::ComposeIconSize(kScreenshotSize).Width()),
|
||||
MAX_IMAGE_SIZE);
|
||||
|
||||
return ScreenshotCoordinate(package->ScreenshotInfoAtIndex(0)->Code(), screenshotSizeScaled + 1,
|
||||
screenshotSizeScaled + 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -386,8 +386,8 @@ PackageColumn::DrawField(BField* field, BRect rect, BView* parent)
|
||||
RatingField* ratingField = dynamic_cast<RatingField*>(field);
|
||||
|
||||
if (packageIconAndTitleField != NULL) {
|
||||
// Scale the bitmap to 16x16
|
||||
BRect r = BRect(0, 0, 15, 15);
|
||||
BSize iconSize = BControlLook::ComposeIconSize(16);
|
||||
BRect r(BPoint(0, 0), iconSize);
|
||||
|
||||
// figure out the placement
|
||||
float x = 0.0;
|
||||
@ -422,14 +422,14 @@ PackageColumn::DrawField(BField* field, BRect rect, BView* parent)
|
||||
status_t bitmapResult;
|
||||
|
||||
bitmapResult = fModel->GetPackageIconRepository().GetIcon(
|
||||
packageIconAndTitleField->PackageName(), 16, bitmapHolderRef);
|
||||
packageIconAndTitleField->PackageName(), iconSize.Width() + 1, bitmapHolderRef);
|
||||
|
||||
if (bitmapResult == B_OK) {
|
||||
if (bitmapHolderRef.IsSet()) {
|
||||
const BBitmap* bitmap = bitmapHolderRef->Bitmap();
|
||||
if (bitmap != NULL && bitmap->IsValid()) {
|
||||
parent->SetDrawingMode(B_OP_ALPHA);
|
||||
BRect viewRect(x, y, x + 15, y + 15);
|
||||
BRect viewRect(BPoint(x, y), iconSize);
|
||||
parent->DrawBitmap(bitmap, bitmap->Bounds(), viewRect);
|
||||
parent->SetDrawingMode(B_OP_OVER);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "SharedIcons.h"
|
||||
|
||||
#include <ControlLook.h>
|
||||
#include <IconUtils.h>
|
||||
#include <Resources.h>
|
||||
|
||||
@ -150,7 +151,8 @@ SharedIcons::_CreateIconForResourceChecked(int32 resourceID, uint32 size,
|
||||
status = B_ERROR;
|
||||
}
|
||||
|
||||
BBitmap* bitmap = new BBitmap(BRect(0, 0, size - 1, size - 1), 0, B_RGBA32);
|
||||
BSize iconSize = BControlLook::ComposeIconSize(size);
|
||||
BBitmap* bitmap = new BBitmap(BRect(BPoint(0, 0), iconSize), 0, B_RGBA32);
|
||||
status = bitmap->InitCheck();
|
||||
|
||||
if (status == B_OK)
|
||||
@ -187,7 +189,8 @@ SharedIcons::_CreateIconForMimeTypeChecked(const char* mimeTypeStr, uint32 size,
|
||||
BBitmap* bitmap = NULL;
|
||||
|
||||
if (status == B_OK) {
|
||||
bitmap = new BBitmap(BRect(0, 0, size - 1, size - 1), 0, B_RGBA32);
|
||||
BSize iconSize = BControlLook::ComposeIconSize(size);
|
||||
bitmap = new BBitmap(BRect(BPoint(0, 0), iconSize), 0, B_RGBA32);
|
||||
status = bitmap->InitCheck();
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,8 @@ RatingView::Draw(BRect updateRect)
|
||||
BSize
|
||||
RatingView::MinSize()
|
||||
{
|
||||
BSize size(16 * 5 + 2 * 4, 16 + 2);
|
||||
return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
|
||||
RatingStarsMetrics metrics(StarBitmap()->Bounds().Size());
|
||||
return BLayoutUtils::ComposeSize(ExplicitMinSize(), metrics.Size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,10 +7,47 @@
|
||||
|
||||
|
||||
#include "HaikuDepotConstants.h"
|
||||
#include "Logger.h"
|
||||
#include "RatingUtils.h"
|
||||
#include "SharedIcons.h"
|
||||
|
||||
|
||||
RatingStarsMetrics::RatingStarsMetrics(BSize starSize)
|
||||
:
|
||||
fStarSize(starSize)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const BSize
|
||||
RatingStarsMetrics::StarSize() const
|
||||
{
|
||||
return fStarSize;
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
RatingStarsMetrics::SpacingBetweenStars() const
|
||||
{
|
||||
return 2.0 * fStarSize.Width() / 16.0;
|
||||
}
|
||||
|
||||
|
||||
const BPoint
|
||||
RatingStarsMetrics::LocationOfStarAtIndex(int index) const
|
||||
{
|
||||
float indexf = static_cast<float>(index);
|
||||
return BPoint(indexf * (fStarSize.Width() + SpacingBetweenStars()), 0.0);
|
||||
}
|
||||
|
||||
|
||||
const BSize
|
||||
RatingStarsMetrics::Size() const
|
||||
{
|
||||
return BSize((fStarSize.Width() * 5) + (SpacingBetweenStars() * 4), fStarSize.Height());
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
RatingUtils::Draw(BView* target, BPoint at, float value)
|
||||
{
|
||||
@ -34,38 +71,32 @@ RatingUtils::Draw(BView* target, BPoint at, float value)
|
||||
RatingUtils::Draw(BView* target, BPoint at, float value,
|
||||
const BBitmap* star)
|
||||
{
|
||||
BRect rect = BOUNDS_RATING;
|
||||
rect.OffsetBy(at);
|
||||
|
||||
// a rectangle covering the whole area of the stars
|
||||
target->FillRect(rect, B_SOLID_LOW);
|
||||
|
||||
if (star == NULL) {
|
||||
debugger("no star icon found in application resources.");
|
||||
HDFATAL("no star icon found in application resources.");
|
||||
return;
|
||||
}
|
||||
|
||||
RatingStarsMetrics metrics(star->Bounds().Size());
|
||||
BRect rect(at, metrics.Size());
|
||||
|
||||
target->FillRect(rect, B_SOLID_LOW);
|
||||
// a rectangle covering the whole area of the stars
|
||||
|
||||
target->SetDrawingMode(B_OP_OVER);
|
||||
|
||||
float x = 0;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
target->DrawBitmap(star, at + BPoint(x, 0));
|
||||
x += SIZE_RATING_STAR + WIDTH_RATING_STAR_SPACING;
|
||||
}
|
||||
for (int i = 0; i < 5; i++)
|
||||
target->DrawBitmap(star, rect.LeftTop() + metrics.LocationOfStarAtIndex(i));
|
||||
|
||||
if (value >= RATING_MIN && value < 5.0f) {
|
||||
target->SetDrawingMode(B_OP_OVER);
|
||||
|
||||
rect = BOUNDS_RATING;
|
||||
rect.right = x - 2;
|
||||
rect.left = ceilf(rect.left + (value / 5.0f) * rect.Width());
|
||||
rect.OffsetBy(at);
|
||||
BRect shadeOverRect = rect;
|
||||
shadeOverRect.left = ceilf(rect.right - (1.0 - (value / 5.0f)) * rect.Width());
|
||||
|
||||
rgb_color color = target->LowColor();
|
||||
color.alpha = 190;
|
||||
target->SetHighColor(color);
|
||||
|
||||
target->SetDrawingMode(B_OP_ALPHA);
|
||||
target->FillRect(rect, B_SOLID_HIGH);
|
||||
target->FillRect(shadeOverRect, B_SOLID_HIGH);
|
||||
}
|
||||
}
|
@ -13,7 +13,23 @@ class BView;
|
||||
class BBitmap;
|
||||
|
||||
|
||||
class RatingUtils {
|
||||
class RatingStarsMetrics
|
||||
{
|
||||
public:
|
||||
RatingStarsMetrics(BSize starSize);
|
||||
|
||||
const BSize StarSize() const;
|
||||
float SpacingBetweenStars() const;
|
||||
const BPoint LocationOfStarAtIndex(int index) const;
|
||||
const BSize Size() const;
|
||||
|
||||
private:
|
||||
BSize fStarSize;
|
||||
};
|
||||
|
||||
|
||||
class RatingUtils
|
||||
{
|
||||
public:
|
||||
static void Draw(BView* target, BPoint at, float value,
|
||||
const BBitmap* star);
|
||||
|
Loading…
Reference in New Issue
Block a user