xref: /haiku/src/apps/packageinstaller/PackageImageViewer.cpp (revision 922e7ba1f3228e6f28db69b0ded8f86eb32dea17)
1 /*
2  * Copyright (c) 2007, Haiku, Inc.
3  * Distributed under the terms of the MIT license.
4  *
5  * Author:
6  *		Łukasz 'Sil2100' Zemczak <sil2100@vexillium.org>
7  */
8 
9 
10 #include "PackageImageViewer.h"
11 
12 #include <BitmapStream.h>
13 #include <Catalog.h>
14 #include <Locale.h>
15 #include <Message.h>
16 #include <Screen.h>
17 #include <TranslatorRoster.h>
18 
19 
20 #undef B_TRANSLATE_CONTEXT
21 #define B_TRANSLATE_CONTEXT "PackageImageViewer"
22 
23 enum {
24 	P_MSG_CLOSE = 'pmic'
25 };
26 
27 
28 ImageView::ImageView(BPositionIO *image)
29 	:
30 	BView(BRect(0, 0, 1, 1), "image_view", B_FOLLOW_NONE, B_WILL_DRAW),
31 	fSuccess(true)
32 {
33 	if (!image) {
34 		fSuccess = false;
35 		return;
36 	}
37 	// Initialize and translate the image
38 	BTranslatorRoster *roster = BTranslatorRoster::Default();
39 	BBitmapStream stream;
40 	if (roster->Translate(image, NULL, NULL, &stream, B_TRANSLATOR_BITMAP)
41 			< B_OK) {
42 		fSuccess = false;
43 		return;
44 	}
45 	stream.DetachBitmap(&fImage);
46 }
47 
48 
49 ImageView::~ImageView()
50 {
51 }
52 
53 
54 void
55 ImageView::AttachedToWindow()
56 {
57 	if (!fSuccess) {
58 		ResizeTo(75, 75);
59 		return;
60 	}
61 
62 	// We need to resize the view depending on what size has the screen and
63 	// the image we will be viewing
64 	BScreen screen(Window());
65 	BRect frame = screen.Frame();
66 	BRect image = fImage->Bounds();
67 
68 	if (image.Width() > (frame.Width() - 100.0f))
69 		image.right = frame.Width() - 100.0f;
70 	if (image.Height() > (frame.Height() - 100.0f))
71 		image.bottom = frame.Height() - 100.f;
72 
73 	ResizeTo(image.Width(), image.Height());
74 }
75 
76 
77 void
78 ImageView::Draw(BRect updateRect)
79 {
80 	if (fSuccess)
81 		DrawBitmapAsync(fImage, Bounds());
82 	else {
83 		float length = StringWidth(B_TRANSLATE("Image not loaded correctly"));
84 		DrawString(B_TRANSLATE("Image not loaded correctly"),
85 			BPoint((Bounds().Width() - length) / 2.0f, 30.0f));
86 	}
87 }
88 
89 
90 void
91 ImageView::MouseUp(BPoint point)
92 {
93 	BWindow *parent = Window();
94 	if (parent)
95 		parent->PostMessage(P_MSG_CLOSE);
96 }
97 
98 
99 // #pragma mark -
100 
101 
102 PackageImageViewer::PackageImageViewer(BPositionIO *image)
103 	:
104 	BWindow(BRect(100, 100, 100, 100), "", B_MODAL_WINDOW,
105 		B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_NOT_CLOSABLE)
106 {
107 	fBackground = new ImageView(image);
108 	AddChild(fBackground);
109 
110 	ResizeTo(fBackground->Bounds().Width(), fBackground->Bounds().Height());
111 
112 	BScreen screen(this);
113 	BRect frame = screen.Frame();
114 	MoveTo((frame.Width() - Bounds().Width()) / 2.0f,
115 			(frame.Height() - Bounds().Height()) / 2.0f);
116 }
117 
118 
119 PackageImageViewer::~PackageImageViewer()
120 {
121 }
122 
123 
124 void
125 PackageImageViewer::Go()
126 {
127 	// Since this class can be thought of as a modified BAlert window, no use
128 	// to reinvent a well fledged wheel. This concept has been borrowed from
129 	// the current BAlert implementation
130 	fSemaphore = create_sem(0, "ImageViewer");
131 	if (fSemaphore < B_OK) {
132 		Quit();
133 		return;
134 	}
135 
136 	BWindow *parent =
137 		dynamic_cast<BWindow *>(BLooper::LooperForThread(find_thread(NULL)));
138 	Show();
139 
140 	if (parent) {
141 		status_t ret;
142 		for (;;) {
143 			do {
144 				ret = acquire_sem_etc(fSemaphore, 1, B_RELATIVE_TIMEOUT, 50000);
145 			} while (ret == B_INTERRUPTED);
146 
147 			if (ret == B_BAD_SEM_ID)
148 				break;
149 			parent->UpdateIfNeeded();
150 		}
151 	}
152 	else {
153 		// Since there are no spinlocks, wait until the semaphore is free
154 		while (acquire_sem(fSemaphore) == B_INTERRUPTED) {
155 		}
156 	}
157 
158 	if (Lock())
159 		Quit();
160 }
161 
162 
163 void
164 PackageImageViewer::MessageReceived(BMessage *msg)
165 {
166 	if (msg->what == P_MSG_CLOSE) {
167 		if (fSemaphore >= B_OK) {
168 			delete_sem(fSemaphore);
169 			fSemaphore = -1;
170 		}
171 	} else
172 		BWindow::MessageReceived(msg);
173 }
174 
175