1 /* 2 * Copyright 2014, Stephan Aßmus <superstippi@gmx.de>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 #include "ScreenshotWindow.h" 7 8 #include <algorithm> 9 #include <stdio.h> 10 11 #include <Autolock.h> 12 #include <Catalog.h> 13 #include <LayoutBuilder.h> 14 15 #include "BitmapView.h" 16 #include "WebAppInterface.h" 17 18 19 #undef B_TRANSLATION_CONTEXT 20 #define B_TRANSLATION_CONTEXT "ScreenshotWindow" 21 22 23 ScreenshotWindow::ScreenshotWindow(BWindow* parent, BRect frame) 24 : 25 BWindow(frame, B_TRANSLATE("Screenshot"), 26 B_FLOATING_WINDOW_LOOK, B_FLOATING_SUBSET_WINDOW_FEEL, 27 B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 28 fDownloadPending(false), 29 fWorkerThread(-1) 30 { 31 AddToSubset(parent); 32 33 fScreenshotView = new BitmapView("screenshot view"); 34 fScreenshotView->SetExplicitMaxSize( 35 BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); 36 37 BGroupView* groupView = new BGroupView(B_VERTICAL); 38 groupView->SetViewColor(0, 0, 0); 39 fScreenshotView->SetLowColor(0, 0, 0); 40 41 // Build layout 42 BLayoutBuilder::Group<>(this, B_VERTICAL) 43 .AddGroup(groupView) 44 .Add(fScreenshotView) 45 .SetInsets(B_USE_WINDOW_INSETS) 46 .End() 47 ; 48 49 CenterOnScreen(); 50 } 51 52 53 ScreenshotWindow::~ScreenshotWindow() 54 { 55 BAutolock locker(&fLock); 56 57 if (fWorkerThread >= 0) 58 wait_for_thread(fWorkerThread, NULL); 59 } 60 61 62 bool 63 ScreenshotWindow::QuitRequested() 64 { 65 if (fOnCloseTarget.IsValid() && fOnCloseMessage.what != 0) 66 fOnCloseTarget.SendMessage(&fOnCloseMessage); 67 68 Hide(); 69 return false; 70 } 71 72 73 void 74 ScreenshotWindow::MessageReceived(BMessage* message) 75 { 76 switch (message->what) { 77 default: 78 BWindow::MessageReceived(message); 79 break; 80 } 81 } 82 83 84 void 85 ScreenshotWindow::SetOnCloseMessage( 86 const BMessenger& messenger, const BMessage& message) 87 { 88 fOnCloseTarget = messenger; 89 fOnCloseMessage = message; 90 } 91 92 93 void 94 ScreenshotWindow::SetPackage(const PackageInfoRef& package) 95 { 96 if (fPackage == package) 97 return; 98 99 fPackage = package; 100 101 BString title = B_TRANSLATE("Screenshot"); 102 if (package.Get() != NULL) { 103 title = package->Title(); 104 _DownloadScreenshot(); 105 } 106 SetTitle(title); 107 } 108 109 110 // #pragma mark - private 111 112 113 void 114 ScreenshotWindow::_DownloadScreenshot() 115 { 116 BAutolock locker(&fLock); 117 118 if (fWorkerThread >= 0) { 119 fDownloadPending = true; 120 return; 121 } 122 123 thread_id thread = spawn_thread(&_DownloadThreadEntry, 124 "Screenshot Loader", B_NORMAL_PRIORITY, this); 125 if (thread >= 0) 126 _SetWorkerThread(thread); 127 } 128 129 130 void 131 ScreenshotWindow::_SetWorkerThread(thread_id thread) 132 { 133 if (!Lock()) 134 return; 135 136 // bool enabled = thread < 0; 137 // 138 // fPreviewsButton->SetEnabled(enabled); 139 // fNextButton->SetEnabled(enabled); 140 // fCloseButton->SetEnabled(enabled); 141 142 if (thread >= 0) { 143 fWorkerThread = thread; 144 resume_thread(fWorkerThread); 145 } else { 146 fWorkerThread = -1; 147 148 if (fDownloadPending) { 149 _DownloadScreenshot(); 150 fDownloadPending = false; 151 } 152 } 153 154 Unlock(); 155 } 156 157 158 int32 159 ScreenshotWindow::_DownloadThreadEntry(void* data) 160 { 161 ScreenshotWindow* window 162 = reinterpret_cast<ScreenshotWindow*>(data); 163 window->_DownloadThread(); 164 window->_SetWorkerThread(-1); 165 return 0; 166 } 167 168 169 void 170 ScreenshotWindow::_DownloadThread() 171 { 172 printf("_DownloadThread()\n"); 173 if (!Lock()) { 174 printf(" failed to lock screenshot window\n"); 175 return; 176 } 177 178 fScreenshotView->UnsetBitmap(); 179 180 ScreenshotInfoList screenshotInfos; 181 if (fPackage.Get() != NULL) 182 screenshotInfos = fPackage->ScreenshotInfos(); 183 184 Unlock(); 185 186 if (screenshotInfos.CountItems() == 0) { 187 printf(" package has no screenshots\n"); 188 return; 189 } 190 191 // Obtain the correct code for the screenshot to display 192 // TODO: Once navigation buttons are added, we could use the 193 // ScreenshotInfo at the "current" index. 194 const ScreenshotInfo& info = screenshotInfos.ItemAtFast(0); 195 196 BMallocIO buffer; 197 WebAppInterface interface; 198 199 // Retrieve screenshot from web-app 200 status_t status = interface.RetrieveScreenshot(info.Code(), 201 info.Width(), info.Height(), &buffer); 202 if (status == B_OK && Lock()) { 203 printf("got screenshot"); 204 fScreenshot = BitmapRef(new(std::nothrow)SharedBitmap(buffer), true); 205 fScreenshotView->SetBitmap(fScreenshot); 206 _ResizeToFitAndCenter(); 207 Unlock(); 208 } else { 209 printf(" failed to download screenshot\n"); 210 } 211 } 212 213 214 void 215 ScreenshotWindow::_ResizeToFitAndCenter() 216 { 217 float minWidth; 218 float minHeight; 219 GetSizeLimits(&minWidth, NULL, &minHeight, NULL); 220 ResizeTo(minWidth, minHeight); 221 CenterOnScreen(); 222 } 223