HaikuDepot: Featured Pkgs View

This change will move the display of the featured packages
from a dynamic layout to one that is static.  This should
improve layout consistency and ui performance as well as
introduce keyboard navigation in the featured packages
list.

Resolves #11675, #15012
Helps #14675

Change-Id: Iddac7a9562763c7a890ec5dcf633e94f84684f43
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2708
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
(cherry picked from commit 9883929b9c)
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2737
This commit is contained in:
Andrew Lindesay 2020-05-16 10:44:48 +12:00 committed by Adrien Destugues
parent 5541a820dc
commit b0f2de3518
8 changed files with 691 additions and 403 deletions

View File

@ -29,6 +29,17 @@ enum {
MSG_LOG_OUT = 'lgot',
};
// when somebody rates a package, there is a numerical
// rating which is expressed in a float 0 --> 5. This
// is visualized by a series of colored stars. These
// constants are related to the geometry of the layout
// of the stars.
#define SIZE_RATING_STAR 16.0
#define WIDTH_RATING_STAR_SPACING 2.0
#define BOUNDS_RATING BRect(0, 0, \
5 * SIZE_RATING_STAR + 4 * WIDTH_RATING_STAR_SPACING, \
SIZE_RATING_STAR)
#define RATING_MISSING -1.0f
#define RATING_MIN 0.0f

View File

@ -142,6 +142,7 @@ local applicationSources =
PackageManager.cpp
RatePackageWindow.cpp
RatingView.cpp
RatingUtils.cpp
support.cpp
ScreenshotWindow.cpp
ScrollableGroupView.cpp

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
/*
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2020, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef FEATURED_PACKAGES_VIEW_H
@ -12,8 +13,7 @@
#include "PackageInfoListener.h"
class BGroupLayout;
class ScrollableGroupView;
class StackedFeaturedPackagesView;
class FeaturedPackagesView : public BView {
@ -21,6 +21,9 @@ public:
FeaturedPackagesView();
virtual ~FeaturedPackagesView();
virtual void FrameResized(float width, float height);
virtual void DoLayout();
void AddPackage(const PackageInfoRef& package);
void RemovePackage(const PackageInfoRef& package);
void Clear();
@ -31,17 +34,13 @@ public:
static void CleanupIcons();
private:
const char* _PackageNameAtIndex(int32 index) const;
int32 _InsertionIndex(
const BString& packageName) const;
int32 _InsertionIndexBinary(const BString& packageName,
int32 startIndex, int32 endIndex) const;
int32 _InsertionIndexLinear(const BString& packageName,
int32 startIndex, int32 endIndex) const;
void _AdjustViews();
private:
BGroupLayout* fPackageListLayout;
ScrollableGroupView* fContainerView;
BScrollView* fScrollView;
StackedFeaturedPackagesView*
fPackagesView;
};

View File

@ -211,9 +211,9 @@ MainWindow::MainWindow(const BMessage& settings)
BPackageRoster().StartWatching(this,
B_WATCH_PACKAGE_INSTALLATION_LOCATIONS);
_StartBulkLoad();
_InitWorkerThreads();
_AdoptModel();
_StartBulkLoad();
}
@ -222,6 +222,8 @@ MainWindow::MainWindow(const BMessage& settings, const PackageInfoRef& package)
BWindow(BRect(50, 50, 650, 350), B_TRANSLATE_SYSTEM_NAME("HaikuDepot"),
B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
fFeaturedPackagesView(NULL),
fPackageListView(NULL),
fWorkStatusView(NULL),
fScreenshotWindow(NULL),
fUserMenu(NULL),
@ -529,11 +531,14 @@ MainWindow::MessageReceived(BMessage* message)
if (wasVisible != isVisible) {
if (!isVisible) {
fPackageListView->RemovePackage(ref);
fFeaturedPackagesView->RemovePackage(ref);
if (fPackageListView != NULL)
fPackageListView->RemovePackage(ref);
if (fFeaturedPackagesView != NULL)
fFeaturedPackagesView->RemovePackage(ref);
} else {
fPackageListView->AddPackage(ref);
if (ref->IsProminent())
if (fPackageListView != NULL)
fPackageListView->AddPackage(ref);
if (fFeaturedPackagesView != NULL && ref->IsProminent())
fFeaturedPackagesView->AddPackage(ref);
}
}
@ -611,8 +616,9 @@ MainWindow::MessageReceived(BMessage* message)
break;
PackageInfoRef package(packageRaw, true);
fPackageListView->AddPackage(package);
if (package->IsProminent())
if (fPackageListView != NULL)
fPackageListView->AddPackage(package);
if (fFeaturedPackagesView != NULL && package->IsProminent())
fFeaturedPackagesView->AddPackage(package);
}
break;
@ -621,8 +627,10 @@ MainWindow::MessageReceived(BMessage* message)
case MSG_UPDATE_SELECTED_PACKAGE:
{
const PackageInfoRef& selectedPackage = fPackageInfoView->Package();
fFeaturedPackagesView->SelectPackage(selectedPackage, true);
fPackageListView->SelectPackage(selectedPackage);
if (fFeaturedPackagesView != NULL)
fFeaturedPackagesView->SelectPackage(selectedPackage, true);
if (fPackageListView != NULL)
fPackageListView->SelectPackage(selectedPackage);
AutoLocker<BLocker> modelLocker(fModel.Lock());
if (!fVisiblePackages.Contains(fPackageInfoView->Package()))
@ -675,7 +683,8 @@ MainWindow::StoreSettings(BMessage& settings) const
settings.AddRect("window frame", Frame());
BMessage columnSettings;
fPackageListView->SaveState(&columnSettings);
if (fPackageListView != NULL)
fPackageListView->SaveState(&columnSettings);
settings.AddMessage("column settings", &columnSettings);
@ -919,6 +928,9 @@ MainWindow::_AdoptModel()
if (Logger::IsTraceEnabled())
printf("adopting model to main window ui");
if (fSinglePackageMode)
return;
{
AutoLocker<BLocker> modelLocker(fModel.Lock());
fVisiblePackages = fModel.CreatePackageList();
@ -927,8 +939,10 @@ MainWindow::_AdoptModel()
atomic_add(&fPackagesToShowListID, 1);
}
fFeaturedPackagesView->Clear();
fPackageListView->Clear();
if (fFeaturedPackagesView != NULL)
fFeaturedPackagesView->Clear();
if (fPackageListView != NULL)
fPackageListView->Clear();
release_sem(fNewPackagesToShowSem);
@ -1055,6 +1069,9 @@ MainWindow::_NotifyWorkStatusChange(const BString& text, float progress)
void
MainWindow::_HandleWorkStatusChangeMessageReceived(const BMessage* message)
{
if (fWorkStatusView == NULL)
return;
BString text;
float progress;

View File

@ -12,6 +12,7 @@
#include <LayoutUtils.h>
#include "HaikuDepotConstants.h"
#include "RatingUtils.h"
RatingView::RatingView(const char* name)
@ -54,36 +55,7 @@ RatingView::StarBitmap()
void
RatingView::Draw(BRect updateRect)
{
FillRect(updateRect, B_SOLID_LOW);
const BBitmap* star = StarBitmap();
if (star == NULL) {
fprintf(stderr, "No star icon found in application resources.\n");
return;
}
SetDrawingMode(B_OP_OVER);
float x = 0;
for (int i = 0; i < 5; i++) {
DrawBitmap(star, BPoint(x, 0));
x += 16 + 2;
}
if (fRating >= RATING_MIN && fRating < 5.0f) {
SetDrawingMode(B_OP_OVER);
BRect rect(Bounds());
rect.right = x - 2;
rect.left = ceilf(rect.left + (fRating / 5.0f) * rect.Width());
rgb_color color = LowColor();
color.alpha = 190;
SetHighColor(color);
SetDrawingMode(B_OP_ALPHA);
FillRect(rect, B_SOLID_HIGH);
}
RatingUtils::Draw(this, BPoint(0, 0), fRating, StarBitmap());
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 2020, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include <View.h>
#include "HaikuDepotConstants.h"
#include "RatingUtils.h"
BReference<SharedBitmap> RatingUtils::sStarBlueBitmap
= BReference<SharedBitmap>(new SharedBitmap(RSRC_STAR_BLUE));
BReference<SharedBitmap> RatingUtils::sStarGrayBitmap
= BReference<SharedBitmap>(new SharedBitmap(RSRC_STAR_GREY));
/*static*/ void
RatingUtils::Draw(BView* target, BPoint at, float value)
{
const BBitmap* star;
if (value < RATING_MIN)
star = sStarGrayBitmap->Bitmap(SharedBitmap::SIZE_16);
else
star = sStarBlueBitmap->Bitmap(SharedBitmap::SIZE_16);
if (star == NULL) {
debugger("no star icon found in application resources.");
return;
}
Draw(target, at, value, star);
}
/*static*/ void
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.");
return;
}
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;
}
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);
rgb_color color = target->LowColor();
color.alpha = 190;
target->SetHighColor(color);
target->SetDrawingMode(B_OP_ALPHA);
target->FillRect(rect, B_SOLID_HIGH);
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2020, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef RATING_UTILS_H
#define RATING_UTILS_H
#include <Referenceable.h>
#include "SharedBitmap.h"
class BView;
class BBitmap;
class RatingUtils {
public:
static void Draw(BView* target, BPoint at, float value,
const BBitmap* star);
static void Draw(BView* target, BPoint at, float value);
private:
static BReference<SharedBitmap>
sStarBlueBitmap;
static BReference<SharedBitmap>
sStarGrayBitmap;
};
#endif // RATING_UTILS_H