xref: /haiku/src/apps/haikudepot/ui/ScreenshotWindow.cpp (revision fce4895d1884da5ae6fb299d23c735c598e690b1)
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