From dead0b80b2329175617ed4136ed26f8245b9ea07 Mon Sep 17 00:00:00 2001 From: PawanYr Date: Wed, 26 Mar 2025 23:14:22 -0400 Subject: [PATCH] HaikuDepot: Add 'All packages' message I've noticed that reviewers often search for something in Haiku Depot on launch, and assume the package doesn't exist when they don't find it under featured/don't check the other tab. This change adds a message to the featured packages view if no results are found, and gives them a link to click to switch tabs. It also adds a loading message to the featured packages view. Also, modify TextSpan::ClickMessage to remove empty message check Change-Id: I045a2a91c945e28e6512232d203da680a70d4d36 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9146 Reviewed-by: humdinger humdinger Tested-by: Commit checker robot Reviewed-by: Andrew Lindesay --- src/apps/haikudepot/HaikuDepotConstants.h | 3 +- .../haikudepot/textview/TextDocumentView.cpp | 3 +- src/apps/haikudepot/textview/TextSpan.h | 2 +- .../haikudepot/ui/FeaturedPackagesView.cpp | 111 +++++++++++++++++- src/apps/haikudepot/ui/FeaturedPackagesView.h | 11 +- src/apps/haikudepot/ui/MainWindow.cpp | 6 + src/apps/haikudepot/ui_generic/LinkView.h | 3 +- 7 files changed, 127 insertions(+), 12 deletions(-) diff --git a/src/apps/haikudepot/HaikuDepotConstants.h b/src/apps/haikudepot/HaikuDepotConstants.h index af6d0d9096..7ff932cd6a 100644 --- a/src/apps/haikudepot/HaikuDepotConstants.h +++ b/src/apps/haikudepot/HaikuDepotConstants.h @@ -28,7 +28,8 @@ enum { MSG_LOG_OUT = 'lgot', MSG_PKG_INSTALL = 'pkgi', MSG_PKG_UNINSTALL = 'pkgu', - MSG_PKG_OPEN = 'pkgo' + MSG_PKG_OPEN = 'pkgo', + MSG_SHOW_ALL_PACKAGES_TAB = 'sapt' }; enum BitmapSize { diff --git a/src/apps/haikudepot/textview/TextDocumentView.cpp b/src/apps/haikudepot/textview/TextDocumentView.cpp index e9d9bb5fa8..65ff3e0791 100644 --- a/src/apps/haikudepot/textview/TextDocumentView.cpp +++ b/src/apps/haikudepot/textview/TextDocumentView.cpp @@ -15,7 +15,6 @@ #include #include - const char* kMimeTypePlainText = "text/plain"; @@ -802,4 +801,4 @@ TextDocumentView::_PasteAllowedChars(const char* str, int32 maxLength) } } } -} \ No newline at end of file +} diff --git a/src/apps/haikudepot/textview/TextSpan.h b/src/apps/haikudepot/textview/TextSpan.h index 6a20bcaa7e..9cacdb3964 100644 --- a/src/apps/haikudepot/textview/TextSpan.h +++ b/src/apps/haikudepot/textview/TextSpan.h @@ -45,7 +45,7 @@ public: { return fCursor; } void SetClickMessage(BMessage* message); inline const BMessage* ClickMessage() const - { return fClickMessage.IsEmpty() ? NULL : &fClickMessage; } + { return &fClickMessage; } private: void _TruncateInsert(int32& start) const; void _TruncateRemove(int32& start, diff --git a/src/apps/haikudepot/ui/FeaturedPackagesView.cpp b/src/apps/haikudepot/ui/FeaturedPackagesView.cpp index 3c990584ab..d7c7a8ebeb 100644 --- a/src/apps/haikudepot/ui/FeaturedPackagesView.cpp +++ b/src/apps/haikudepot/ui/FeaturedPackagesView.cpp @@ -1,7 +1,8 @@ /* - * Copyright 2013-214, Stephan Aßmus . + * Copyright 2013-2014, Stephan Aßmus . * Copyright 2017, Julian Harnath . * Copyright 2020-2025, Andrew Lindesay . + * Copyright 2025, Pawan Yerramilli . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -21,11 +22,12 @@ #include #include "BitmapView.h" +#include "Cursor.h" #include "HaikuDepotConstants.h" +#include "InterfaceDefs.h" #include "LocaleUtils.h" #include "Logger.h" #include "MainWindow.h" -#include "MarkupTextView.h" #include "PackageUtils.h" #include "RatingUtils.h" #include "RatingView.h" @@ -50,6 +52,11 @@ // The faction of an M-space that is left between the title and the first trailing icon. #define TITLE_RIGHT_TRAILING_ICON_PADDING_M_FACTOR 0.1 +enum { + PACKAGE_BULDING_CARD = 0, + PACKAGE_LIST_CARD = 1, + NO_RESULTS_CARD = 2 +}; // #pragma mark - PackageView @@ -966,22 +973,62 @@ private: FeaturedPackagesView::FeaturedPackagesView(Model& model) : BView(B_TRANSLATE("Featured packages"), 0), - fModel(model) + fModel(model), + fIsLoadingAndNoData(false) { fPackagesView = new StackedFeaturedPackagesView(fModel); fScrollView = new BScrollView("featured packages scroll view", fPackagesView, 0, false, true, B_FANCY_BORDER); - BLayoutBuilder::Group<>(this).Add(fScrollView, 1.0f); -} + _BuildNoResultsView(); + BStringView* pleaseWaitText = new BStringView( + "please wait text", B_TRANSLATE("Creating package list" B_UTF8_ELLIPSIS)); + + pleaseWaitText->SetExplicitAlignment( + BAlignment(B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER)); + + fFeaturedCardLayout = new BCardLayout(); + SetLayout(fFeaturedCardLayout); + + BGroupView* pleaseWaitGroup = new BGroupView("please wait"); + pleaseWaitGroup->SetViewColor(ui_color(B_LIST_BACKGROUND_COLOR)); + AddChild(pleaseWaitGroup); + + BGroupView* foundResultsGroup = new BGroupView("search results"); + AddChild(foundResultsGroup); + + BGroupView* noResultsGroup = new BGroupView("no search results"); + noResultsGroup->SetViewColor(ui_color(B_LIST_BACKGROUND_COLOR)); + AddChild(noResultsGroup); + + BLayoutBuilder::Group<>(pleaseWaitGroup) + .Add(pleaseWaitText) + .SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); + BLayoutBuilder::Group<>(foundResultsGroup).Add(fScrollView, 1.0f); + BLayoutBuilder::Group<>(noResultsGroup) + .AddGroup(B_VERTICAL) + .AddGlue() + .Add(fNoResultsView) + .AddGlue() + .End() + .SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); + _AdjustViews(); +} FeaturedPackagesView::~FeaturedPackagesView() { } +void +FeaturedPackagesView::AttachedToWindow() +{ + fNoResultsView->SetTarget(Window()); +} + + void FeaturedPackagesView::RetainPackages(const std::vector& packages) { @@ -994,6 +1041,9 @@ void FeaturedPackagesView::AddRemovePackages(const std::vector& addedPackages, const std::vector& removedPackages) { + if (!addedPackages.empty()) + fIsLoadingAndNoData = false; + if (!addedPackages.empty() || !removedPackages.empty()) { fPackagesView->AddRemovePackages(addedPackages, removedPackages); _AdjustViews(); @@ -1045,8 +1095,59 @@ FeaturedPackagesView::HandlePackagesChanged(const PackageInfoEvents& events) } +void +FeaturedPackagesView::SetLoading(bool isLoading) +{ + if ((isLoading && fPackagesView->IsEmpty()) != fIsLoadingAndNoData) { + fIsLoadingAndNoData = !fIsLoadingAndNoData; + _AdjustViews(); + } +} + + +void +FeaturedPackagesView::_BuildNoResultsView() +{ + fNoResultsView = new TextDocumentView(); + TextDocumentRef noResultsTextDocument = new TextDocument(); + ParagraphStyle paragraphStyle; + paragraphStyle.SetAlignment(ALIGN_CENTER); + Paragraph paragraph(paragraphStyle); + + TextSpan prefix; + prefix.SetText(B_TRANSLATE("No results? ")); + + CharacterStyle linkStyle; + linkStyle.SetForegroundColor(ui_color(B_LINK_TEXT_COLOR)); + TextSpan link(B_TRANSLATE_COMMENT( + "Click here", "Appears in the sentence 'Click here to search all packages.'"), linkStyle); + link.SetClickMessage(new BMessage(MSG_SHOW_ALL_PACKAGES_TAB)); + BCursor cursor(B_CURSOR_ID_SYSTEM_DEFAULT); + link.SetCursor(cursor); + + TextSpan suffix; + suffix.SetText(B_TRANSLATE_COMMENT(" to search all packages.", + "Appears in the sentence 'Click here to search all packages.'")); + + paragraph.Append(prefix); + paragraph.Append(link); + paragraph.Append(suffix); + noResultsTextDocument->Append(paragraph); + fNoResultsView->SetTextDocument(noResultsTextDocument); + fNoResultsView->SetSelectionEnabled(false); + fNoResultsView->SetViewUIColor(B_LIST_BACKGROUND_COLOR); +} + + void FeaturedPackagesView::_AdjustViews() { + if (fIsLoadingAndNoData) + fFeaturedCardLayout->SetVisibleItem(PACKAGE_BULDING_CARD); + else if (fPackagesView->IsEmpty()) + fFeaturedCardLayout->SetVisibleItem(NO_RESULTS_CARD); + else + fFeaturedCardLayout->SetVisibleItem(PACKAGE_LIST_CARD); + fScrollView->FrameResized(fScrollView->Frame().Width(), fScrollView->Frame().Height()); } diff --git a/src/apps/haikudepot/ui/FeaturedPackagesView.h b/src/apps/haikudepot/ui/FeaturedPackagesView.h index d03f4c986f..1d87dbdf43 100644 --- a/src/apps/haikudepot/ui/FeaturedPackagesView.h +++ b/src/apps/haikudepot/ui/FeaturedPackagesView.h @@ -9,11 +9,14 @@ #include +#include #include +#include #include "Model.h" #include "PackageInfo.h" #include "PackageInfoListener.h" +#include "TextDocumentView.h" class StackedFeaturedPackagesView; @@ -25,6 +28,7 @@ public: virtual ~FeaturedPackagesView(); virtual void DoLayout(); + void AttachedToWindow(); void RetainPackages(const std::vector& packages); void AddRemovePackages(const std::vector& addedPackages, @@ -38,16 +42,21 @@ public: void HandlePackagesChanged(const PackageInfoEvents& events); + void SetLoading(bool isLoading); + private: void _AdjustViews(); void _HandlePackageChanged(const PackageInfoEvent& event); + void _BuildNoResultsView(); private: Model& fModel; BScrollView* fScrollView; StackedFeaturedPackagesView* fPackagesView; + BCardLayout* fFeaturedCardLayout; + TextDocumentView* fNoResultsView; + bool fIsLoadingAndNoData; }; - #endif // FEATURED_PACKAGES_VIEW_H diff --git a/src/apps/haikudepot/ui/MainWindow.cpp b/src/apps/haikudepot/ui/MainWindow.cpp index e506c665ad..8d62412479 100644 --- a/src/apps/haikudepot/ui/MainWindow.cpp +++ b/src/apps/haikudepot/ui/MainWindow.cpp @@ -672,6 +672,10 @@ MainWindow::MessageReceived(BMessage* message) break; } + case MSG_SHOW_ALL_PACKAGES_TAB: + fListTabs->Select(TAB_ALL_PACKAGES); + break; + default: BWindow::MessageReceived(message); break; @@ -1193,6 +1197,7 @@ MainWindow::_StartBulkLoad(bool force) } fPackageInfoView->Clear(); + fFeaturedPackagesView->SetLoading(true); fRefreshRepositoriesItem->SetEnabled(false); ProcessCoordinator* bulkLoadCoordinator @@ -1213,6 +1218,7 @@ MainWindow::_BulkLoadCompleteReceived(status_t errorStatus) "logs." ALERT_MSG_LOGS_USER_GUIDE)); } + fFeaturedPackagesView->SetLoading(false); fRefreshRepositoriesItem->SetEnabled(true); _AdoptModel(); _UpdateAvailableRepositories(); diff --git a/src/apps/haikudepot/ui_generic/LinkView.h b/src/apps/haikudepot/ui_generic/LinkView.h index 9e344b8db6..5798c88bce 100644 --- a/src/apps/haikudepot/ui_generic/LinkView.h +++ b/src/apps/haikudepot/ui_generic/LinkView.h @@ -12,8 +12,7 @@ class LinkView : public BStringView, public BInvoker { public: - LinkView(const char* name, const char* string, - BMessage* message); + LinkView(const char* name, const char* string, BMessage* message); virtual void AttachedToWindow();