HaikuDepot: begin support for multiple screenshots

* Initial support for displaying multiple screenshots for packages
  which have more than one. Still rough and unfinished.

  Screenshot window now has a toolbar with prev/next buttons and
  a busy loading indicator. Switching through the screenshots works.

  There's currently a server-side bug which makes all data turn up
  15 times in the JSON file, so please don't report a bug about
  HaikuDepot showing 15 or 30 screenshots available when it's really
  just 1 or 2 :)

  Still to be done: toolbar icons instead of text labels; better
  handling of screenshot window resizing; maybe thumbnails of
  screenshots and preloading other screenshots in the background.
  Main window also needs a way to indicate that there are more
  screenshots than the one thumbnail, needs some more thought about
  how that might look.

  This concludes my HaikuDepot commits from the coding sprint at
  KDC 2017 Toulouse!
This commit is contained in:
Julian Harnath 2017-11-24 18:11:54 +01:00
parent 74e4161139
commit c210060f38
2 changed files with 97 additions and 2 deletions

View File

@ -12,7 +12,9 @@
#include <Autolock.h>
#include <Catalog.h>
#include <LayoutBuilder.h>
#include <StringView.h>
#include "BarberPole.h"
#include "BitmapView.h"
#include "WebAppInterface.h"
@ -31,11 +33,31 @@ ScreenshotWindow::ScreenshotWindow(BWindow* parent, BRect frame)
BWindow(frame, B_TRANSLATE("Screenshot"),
B_FLOATING_WINDOW_LOOK, B_FLOATING_SUBSET_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
fNumScreenshots(0),
fDownloadPending(false),
fWorkerThread(-1)
{
AddToSubset(parent);
atomic_set(&fCurrentScreenshotIndex, 0);
fBarberPole = new BarberPole("barber pole");
fBarberPole->SetExplicitMaxSize(BSize(200, B_SIZE_UNLIMITED));
fIndexView = new BStringView("screenshot index", NULL);
fToolBar = new BToolBar();
fToolBar->AddAction(MSG_PREVIOUS_SCREENSHOT, this, NULL /* todo: icon */,
B_TRANSLATE("Show previous screenshot"),
B_TRANSLATE("Previous"));
fToolBar->AddAction(MSG_NEXT_SCREENSHOT, this, NULL /* todo: icon */,
B_TRANSLATE("Show next screenshot"),
B_TRANSLATE("Next"));
fToolBar->AddGlue();
fToolBar->AddView(fIndexView);
fToolBar->AddGlue();
fToolBar->AddView(fBarberPole);
fScreenshotView = new BitmapView("screenshot view");
fScreenshotView->SetExplicitMaxSize(
BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
@ -44,7 +66,10 @@ ScreenshotWindow::ScreenshotWindow(BWindow* parent, BRect frame)
groupView->SetViewColor(kBackgroundColor);
// Build layout
BLayoutBuilder::Group<>(this, B_VERTICAL)
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
.SetInsets(0, 5, 0, 0)
.Add(fToolBar)
.AddStrut(5)
.AddGroup(groupView)
.Add(fScreenshotView)
.SetInsets(B_USE_WINDOW_INSETS)
@ -83,6 +108,28 @@ void
ScreenshotWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_NEXT_SCREENSHOT:
{
atomic_add(&fCurrentScreenshotIndex, 1);
_UpdateToolBar();
_DownloadScreenshot();
break;
}
case MSG_PREVIOUS_SCREENSHOT:
atomic_add(&fCurrentScreenshotIndex, -1);
_UpdateToolBar();
_DownloadScreenshot();
break;
case MSG_DOWNLOAD_START:
fBarberPole->Start();
break;
case MSG_DOWNLOAD_STOP:
fBarberPole->Stop();
break;
default:
BWindow::MessageReceived(message);
break;
@ -113,6 +160,11 @@ ScreenshotWindow::SetPackage(const PackageInfoRef& package)
_DownloadScreenshot();
}
SetTitle(title);
atomic_set(&fCurrentScreenshotIndex, 0);
fNumScreenshots = fPackage->ScreenshotInfos().CountItems();
_UpdateToolBar();
}
@ -200,14 +252,21 @@ ScreenshotWindow::_DownloadThread()
// Obtain the correct code for the screenshot to display
// TODO: Once navigation buttons are added, we could use the
// ScreenshotInfo at the "current" index.
const ScreenshotInfo& info = screenshotInfos.ItemAtFast(0);
const ScreenshotInfo& info = screenshotInfos.ItemAtFast(
atomic_get(&fCurrentScreenshotIndex));
BMallocIO buffer;
WebAppInterface interface;
BMessenger messenger(this);
messenger.SendMessage(MSG_DOWNLOAD_START);
// Retrieve screenshot from web-app
status_t status = interface.RetrieveScreenshot(info.Code(),
info.Width(), info.Height(), &buffer);
messenger.SendMessage(MSG_DOWNLOAD_STOP);
if (status == B_OK && Lock()) {
printf("got screenshot");
fScreenshot = BitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
@ -229,3 +288,20 @@ ScreenshotWindow::_ResizeToFitAndCenter()
ResizeTo(minWidth, minHeight);
CenterOnScreen();
}
void
ScreenshotWindow::_UpdateToolBar()
{
int32 currentIndex = atomic_get(&fCurrentScreenshotIndex);
fToolBar->SetActionEnabled(MSG_PREVIOUS_SCREENSHOT,
currentIndex > 0);
fToolBar->SetActionEnabled(MSG_NEXT_SCREENSHOT,
currentIndex < fNumScreenshots - 2);
BString text;
text << currentIndex + 1;
text << " / ";
text << fNumScreenshots;
fIndexView->SetText(text);
}

View File

@ -7,12 +7,23 @@
#include <Locker.h>
#include <Messenger.h>
#include <ToolBar.h>
#include <Window.h>
#include "PackageInfo.h"
class BarberPole;
class BitmapView;
class BStringView;
enum {
MSG_NEXT_SCREENSHOT = 'nscr',
MSG_PREVIOUS_SCREENSHOT = 'pscr',
MSG_DOWNLOAD_START = 'dlst',
MSG_DOWNLOAD_STOP = 'dlsp',
};
class ScreenshotWindow : public BWindow {
@ -39,14 +50,22 @@ private:
void _DownloadThread();
void _ResizeToFitAndCenter();
void _UpdateToolBar();
private:
BMessenger fOnCloseTarget;
BMessage fOnCloseMessage;
BToolBar* fToolBar;
BarberPole* fBarberPole;
BStringView* fIndexView;
BitmapRef fScreenshot;
BitmapView* fScreenshotView;
int32 fNumScreenshots;
int32 fCurrentScreenshotIndex; // atomic
PackageInfoRef fPackage;
bool fDownloadPending;