HaikuDepot: Installed icon on list view

How the installed tick indicator on package
list view.

Change-Id: Ib7ea0de3d268f7eb16acdd5d575eb6da096170b2
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8510
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
This commit is contained in:
Andrew Lindesay 2024-10-29 08:48:15 +13:00 committed by Jérôme Duval
parent eb2080d241
commit 7d8bc41066

View File

@ -79,13 +79,19 @@ class PackageIconAndTitleField : public BStringField {
public:
PackageIconAndTitleField(
const char* packageName,
const char* string);
const char* string,
bool isActivated);
virtual ~PackageIconAndTitleField();
const BString PackageName() const
{ return fPackageName; }
bool IsActivated() const
{ return fIsActivated; }
private:
const BString fPackageName;
const bool fIsActivated;
};
@ -236,11 +242,12 @@ private:
// #pragma mark - PackageIconAndTitleField
PackageIconAndTitleField::PackageIconAndTitleField(const char* packageName,
const char* string)
PackageIconAndTitleField::PackageIconAndTitleField(const char* packageName, const char* string,
bool isActivated)
:
Inherited(string),
fPackageName(packageName)
fPackageName(packageName),
fIsActivated(isActivated)
{
}
@ -391,38 +398,65 @@ PackageColumn::DrawField(BField* field, BRect rect, BView* parent)
RatingField* ratingField = dynamic_cast<RatingField*>(field);
if (packageIconAndTitleField != NULL) {
// TODO (andponlin) factor this out as this method is getting too large.
BSize iconSize = BControlLook::ComposeIconSize(16);
BRect r(BPoint(0, 0), iconSize);
BSize indicatorSize = BControlLook::ComposeIconSize(8);
BRect iconRect;
BRect titleRect;
BRect activatedIndicatorRect;
float titleTextWidth = 0.0f;
float textMargin = 8.0f; // copied from ColumnTypes.cpp
bool showActivated = packageIconAndTitleField->IsActivated();
// figure out the placement
float x = 0.0;
float y = rect.top + ((rect.Height() - r.Height()) / 2) - 1;
float width = 0.0;
// If there is not enough space then drop the "activated" indicator in order to make more
// room for the title.
switch (Alignment()) {
default:
case B_ALIGN_LEFT:
case B_ALIGN_CENTER:
x = rect.left + sTextMargin;
width = rect.right - (x + r.Width()) - (2 * sTextMargin);
r.Set(x + r.Width(), rect.top, rect.right - width, rect.bottom);
break;
if (showActivated) {
static float sMinimalTextPart = -1.0;
case B_ALIGN_RIGHT:
x = rect.right - sTextMargin - r.Width();
width = (x - rect.left - (2 * sTextMargin));
r.Set(rect.left, rect.top, rect.left + width, rect.bottom);
break;
if (sMinimalTextPart < 0.0)
sMinimalTextPart = parent->StringWidth("M") * 5.0;
float minimalWidth
= iconSize.Width() + indicatorSize.Width() + sTextMargin + sMinimalTextPart;
if (rect.Width() <= minimalWidth)
showActivated = false;
}
if (width != packageIconAndTitleField->Width()) {
BString truncatedString(packageIconAndTitleField->String());
parent->TruncateString(&truncatedString, fTruncateMode, width + 2);
packageIconAndTitleField->SetClippedString(truncatedString.String());
packageIconAndTitleField->SetWidth(width);
}
// Calculate the location of the icon.
iconRect = BRect(BPoint(rect.left + sTextMargin,
rect.top + ((rect.Height() - iconSize.Height()) / 2) - 1),
iconSize);
// Calculate the location of the title text.
titleRect = rect;
titleRect.left = iconRect.right;
if (showActivated)
titleRect.right -= (indicatorSize.Width() + sTextMargin);
// Figure out if the text needs to be truncated.
float textWidth = titleRect.Width() - (2.0 * textMargin);
BString truncatedString(packageIconAndTitleField->String());
parent->TruncateString(&truncatedString, fTruncateMode, textWidth);
packageIconAndTitleField->SetClippedString(truncatedString.String());
titleTextWidth = parent->StringWidth(truncatedString);
// Calculate the location of the activated indicator.
activatedIndicatorRect
= BRect(BPoint(ceilf(titleRect.left + titleTextWidth + (1.5f * textMargin)) + 0.5f,
ceilf(iconRect.top) + 0.5f),
indicatorSize);
// Draw the icon.
// draw the bitmap
BitmapHolderRef bitmapHolderRef;
status_t bitmapResult;
@ -434,15 +468,26 @@ PackageColumn::DrawField(BField* field, BRect rect, BView* parent)
const BBitmap* bitmap = bitmapHolderRef->Bitmap();
if (bitmap != NULL && bitmap->IsValid()) {
parent->SetDrawingMode(B_OP_ALPHA);
BRect viewRect(BPoint(x, y), iconSize);
parent->DrawBitmap(bitmap, bitmap->Bounds(), viewRect);
parent->DrawBitmap(bitmap, bitmap->Bounds(), iconRect,
B_FILTER_BITMAP_BILINEAR);
parent->SetDrawingMode(B_OP_OVER);
}
}
}
// draw the string
DrawString(packageIconAndTitleField->ClippedString(), parent, r);
// Draw the title.
DrawString(packageIconAndTitleField->ClippedString(), parent, titleRect);
// draw the installed indicator icon.
if (showActivated) {
const BBitmap* installedIconBitmap = SharedIcons::IconInstalled16Scaled()->Bitmap();
parent->SetDrawingMode(B_OP_ALPHA);
parent->DrawBitmap(installedIconBitmap, installedIconBitmap->Bounds(),
activatedIndicatorRect, B_FILTER_BITMAP_BILINEAR);
parent->SetDrawingMode(B_OP_OVER);
}
} else if (stringField != NULL) {
@ -634,7 +679,10 @@ PackageRow::UpdateIconAndTitle()
BString title;
PackageUtils::TitleOrName(fPackage, title);
SetField(new PackageIconAndTitleField(fPackage->Name(), title), kTitleColumn);
BField* field
= new PackageIconAndTitleField(fPackage->Name(), title, fPackage->State() == ACTIVATED);
SetField(field, kTitleColumn);
}
@ -935,11 +983,11 @@ PackageListView::MessageReceived(BMessage* message)
|| message->FindUInt32("changes", &changes) != B_OK) {
break;
}
BAutolock _(fModel->Lock());
PackageRow* row = _FindRow(name);
if (row != NULL) {
if ((changes & PKG_CHANGED_LOCALIZED_TEXT) != 0) {
if ((changes & PKG_CHANGED_LOCALIZED_TEXT) != 0
|| (changes & PKG_CHANGED_STATE) != 0) {
row->UpdateIconAndTitle();
row->UpdateSummary();
}