From 87038da74ffcc97549794862bb0ff18ec2f83229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Fri, 5 Sep 2014 23:11:02 +0200 Subject: [PATCH] HaikDepot: Lazily load screenshots. The first one is displayed. Clicking the thumbnail does nothing, as before. (There is a TODO in the code to open the bigger version.) --- src/apps/haikudepot/Model.cpp | 79 +++++++++++++++++++++++++++++++++++ src/apps/haikudepot/Model.h | 5 +++ 2 files changed, 84 insertions(+) diff --git a/src/apps/haikudepot/Model.cpp b/src/apps/haikudepot/Model.cpp index fafbeadfd9..1810edc9e3 100644 --- a/src/apps/haikudepot/Model.cpp +++ b/src/apps/haikudepot/Model.cpp @@ -616,6 +616,18 @@ Model::PopulatePackage(const PackageInfoRef& package, uint32 flags) } } } + + if ((flags & POPULATE_SCREEN_SHOTS) != 0) { + ScreenshotInfoList screenshotInfos; + { + BAutolock locker(&fLock); + screenshotInfos = package->ScreenshotInfos(); + } + for (int i = 0; i < screenshotInfos.CountItems(); i++) { + const ScreenshotInfo& info = screenshotInfos.ItemAtFast(i); + _PopulatePackageScreenshot(package, info, 400, false); + } + } } @@ -959,6 +971,12 @@ Model::_PopulatePackageInfo(const PackageInfoRef& package, const BMessage& data) printf("Populated package info for %s: %s\n", package->Title().String(), foundInfo.String()); } + + // If the user already clicked this package, remove it from the + // list of populated packages, so that clicking it again will + // populate any additional information. + // TODO: Trigger re-populating if the package is currently showing. + fPopulatedPackages.Remove(package); } @@ -1016,6 +1034,67 @@ Model::_PopulatePackageIcon(const PackageInfoRef& package, bool fromCacheOnly) } +void +Model::_PopulatePackageScreenshot(const PackageInfoRef& package, + const ScreenshotInfo& info, int32 scaledWidth, bool fromCacheOnly) +{ + // See if there is a cached screenshot + BFile screenshotFile; + BPath screenshotCachePath; + bool fileExists = false; + BString screenshotName(info.Code()); + screenshotName << "@" << scaledWidth; + screenshotName << ".png"; + time_t modifiedTime; + if (find_directory(B_USER_CACHE_DIRECTORY, &screenshotCachePath) == B_OK + && screenshotCachePath.Append("HaikuDepot/Screenshots") == B_OK + && create_directory(screenshotCachePath.Path(), 0777) == B_OK + && screenshotCachePath.Append(screenshotName) == B_OK) { + // Try opening the file in read-only mode, which will fail if its + // not a file or does not exist. + fileExists = screenshotFile.SetTo(screenshotCachePath.Path(), + B_READ_ONLY) == B_OK; + if (fileExists) + screenshotFile.GetModificationTime(&modifiedTime); + } + + if (fileExists) { + time_t now; + time(&now); + if (fromCacheOnly || now - modifiedTime < 60 * 60) { + // Cache file is recent enough, just use it and return. + BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(screenshotFile), + true); + BAutolock locker(&fLock); + package->AddScreenshot(bitmapRef); + return; + } + } + + if (fromCacheOnly) + return; + + // Retrieve screenshot from web-app + WebAppInterface interface; + BMallocIO buffer; + + int32 scaledHeight = scaledWidth * info.Height() / info.Width(); + + status_t status = interface.RetrieveScreenshot(info.Code(), + scaledWidth, scaledHeight, &buffer); + if (status == B_OK) { + BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(buffer), true); + BAutolock locker(&fLock); + package->AddScreenshot(bitmapRef); + locker.Unlock(); + if (screenshotFile.SetTo(screenshotCachePath.Path(), + B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) == B_OK) { + screenshotFile.Write(buffer.Buffer(), buffer.BufferLength()); + } + } +} + + bool Model::_HasNativeIcon(const BMessage& message) const { diff --git a/src/apps/haikudepot/Model.h b/src/apps/haikudepot/Model.h index d4568927fe..09b94cd2aa 100644 --- a/src/apps/haikudepot/Model.h +++ b/src/apps/haikudepot/Model.h @@ -117,6 +117,11 @@ private: const PackageInfoRef& package, bool fromCacheOnly); bool _HasNativeIcon(const BMessage& message) const; + void _PopulatePackageScreenshot( + const PackageInfoRef& package, + const ScreenshotInfo& info, + int32 scaledWidth, + bool fromCacheOnly); private: BLocker fLock;