Files
haiku-beta6/src/apps/packageinstaller/PackageImageViewer.cpp
T

170 lines
3.4 KiB
C++

/*
* Copyright (c) 2007, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Author:
* Łukasz 'Sil2100' Zemczak <[email protected]>
*/
#include "PackageImageViewer.h"
#include <BitmapStream.h>
#include <Catalog.h>
#include <Locale.h>
#include <Message.h>
#include <Screen.h>
#include <TranslatorRoster.h>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "PackageImageViewer"
ImageView::ImageView(BPositionIO* imageIO)
:
BView(BRect(0, 0, 1, 1), "image_view", B_FOLLOW_NONE, B_WILL_DRAW),
fImage(NULL)
{
if (imageIO == NULL)
return;
// Initialize and translate the image
BTranslatorRoster* roster = BTranslatorRoster::Default();
BBitmapStream stream;
if (roster->Translate(imageIO, NULL, NULL, &stream, B_TRANSLATOR_BITMAP)
!= B_OK) {
return;
}
stream.DetachBitmap(&fImage);
}
ImageView::~ImageView()
{
delete fImage;
}
void
ImageView::AttachedToWindow()
{
if (fImage == NULL) {
ResizeTo(75, 75);
return;
}
// We need to resize the view depending on what size has the screen and
// the image we will be viewing
BScreen screen(Window());
BRect frame = screen.Frame();
BRect image = fImage->Bounds();
if (image.Width() > (frame.Width() - 100.0f))
image.right = frame.Width() - 100.0f;
if (image.Height() > (frame.Height() - 100.0f))
image.bottom = frame.Height() - 100.f;
ResizeTo(image.Width(), image.Height());
}
void
ImageView::Draw(BRect updateRect)
{
if (fImage != NULL)
DrawBitmapAsync(fImage, Bounds());
else {
const char* message = B_TRANSLATE("Image not loaded correctly");
float width = StringWidth(message);
DrawString(message, BPoint((Bounds().Width() - width) / 2.0f, 30.0f));
}
}
void
ImageView::MouseUp(BPoint point)
{
BWindow* window = Window();
if (window != NULL)
window->PostMessage(B_QUIT_REQUESTED);
}
// #pragma mark -
PackageImageViewer::PackageImageViewer(BPositionIO* imageIO)
:
BWindow(BRect(100, 100, 100, 100), "", B_MODAL_WINDOW,
B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_NOT_CLOSABLE)
{
fBackground = new ImageView(imageIO);
AddChild(fBackground);
ResizeTo(fBackground->Bounds().Width(), fBackground->Bounds().Height());
BScreen screen(this);
BRect frame = screen.Frame();
MoveTo((frame.Width() - Bounds().Width()) / 2.0f,
(frame.Height() - Bounds().Height()) / 2.0f);
}
PackageImageViewer::~PackageImageViewer()
{
}
bool
PackageImageViewer::QuitRequested()
{
if (fSemaphore >= B_OK) {
delete_sem(fSemaphore);
fSemaphore = -1;
}
return true;
}
void
PackageImageViewer::Go()
{
// Since this class can be thought of as a modified BAlert window, no use
// to reinvent a well fledged wheel. This concept has been borrowed from
// the current BAlert implementation
fSemaphore = create_sem(0, "ImageViewer");
if (fSemaphore < B_OK) {
Quit();
return;
}
thread_id callingThread = find_thread(NULL);
BWindow* window = dynamic_cast<BWindow*>(BLooper::LooperForThread(
callingThread));
Show();
if (window != NULL) {
// Make sure calling window thread, which is blocked here, is updating
// the window from time to time.
status_t ret;
for (;;) {
do {
ret = acquire_sem_etc(fSemaphore, 1, B_RELATIVE_TIMEOUT, 50000);
} while (ret == B_INTERRUPTED);
if (ret == B_BAD_SEM_ID)
break;
window->UpdateIfNeeded();
}
} else {
// Since there are no spinlocks, wait until the semaphore is free
while (acquire_sem(fSemaphore) == B_INTERRUPTED) {
}
}
if (Lock())
Quit();
}