144f919daSRyan Leavengood /* 244f919daSRyan Leavengood * Copyright (c) 2007, Haiku, Inc. 344f919daSRyan Leavengood * Distributed under the terms of the MIT license. 444f919daSRyan Leavengood * 544f919daSRyan Leavengood * Author: 644f919daSRyan Leavengood * Łukasz 'Sil2100' Zemczak <sil2100@vexillium.org> 744f919daSRyan Leavengood */ 844f919daSRyan Leavengood 944f919daSRyan Leavengood 1044f919daSRyan Leavengood #include "PackageImageViewer.h" 1144f919daSRyan Leavengood 1244f919daSRyan Leavengood #include <BitmapStream.h> 13*091440e0SStephan Aßmus #include <Catalog.h> 14*091440e0SStephan Aßmus #include <Locale.h> 1544f919daSRyan Leavengood #include <Message.h> 1644f919daSRyan Leavengood #include <Screen.h> 1744f919daSRyan Leavengood #include <TranslatorRoster.h> 1844f919daSRyan Leavengood 1944f919daSRyan Leavengood 20*091440e0SStephan Aßmus #undef TR_CONTEXT 21*091440e0SStephan Aßmus #define TR_CONTEXT "PackageImageViewer" 2244f919daSRyan Leavengood 2344f919daSRyan Leavengood enum { 2444f919daSRyan Leavengood P_MSG_CLOSE = 'pmic' 2544f919daSRyan Leavengood }; 2644f919daSRyan Leavengood 2744f919daSRyan Leavengood 2844f919daSRyan Leavengood ImageView::ImageView(BPositionIO *image) 29*091440e0SStephan Aßmus : 30*091440e0SStephan Aßmus BView(BRect(0, 0, 1, 1), "image_view", B_FOLLOW_NONE, B_WILL_DRAW), 3144f919daSRyan Leavengood fSuccess(true) 3244f919daSRyan Leavengood { 3344f919daSRyan Leavengood if (!image) { 3444f919daSRyan Leavengood fSuccess = false; 3544f919daSRyan Leavengood return; 3644f919daSRyan Leavengood } 3744f919daSRyan Leavengood // Initialize and translate the image 3844f919daSRyan Leavengood BTranslatorRoster *roster = BTranslatorRoster::Default(); 3944f919daSRyan Leavengood BBitmapStream stream; 4044f919daSRyan Leavengood if (roster->Translate(image, NULL, NULL, &stream, B_TRANSLATOR_BITMAP) 4144f919daSRyan Leavengood < B_OK) { 4244f919daSRyan Leavengood fSuccess = false; 4344f919daSRyan Leavengood return; 4444f919daSRyan Leavengood } 4544f919daSRyan Leavengood stream.DetachBitmap(&fImage); 4644f919daSRyan Leavengood } 4744f919daSRyan Leavengood 4844f919daSRyan Leavengood 4944f919daSRyan Leavengood ImageView::~ImageView() 5044f919daSRyan Leavengood { 5144f919daSRyan Leavengood } 5244f919daSRyan Leavengood 5344f919daSRyan Leavengood 5444f919daSRyan Leavengood void 5544f919daSRyan Leavengood ImageView::AttachedToWindow() 5644f919daSRyan Leavengood { 5744f919daSRyan Leavengood if (!fSuccess) { 5844f919daSRyan Leavengood ResizeTo(75, 75); 5944f919daSRyan Leavengood return; 6044f919daSRyan Leavengood } 6144f919daSRyan Leavengood 6244f919daSRyan Leavengood // We need to resize the view depending on what size has the screen and 6344f919daSRyan Leavengood // the image we will be viewing 6444f919daSRyan Leavengood BScreen screen(Window()); 6544f919daSRyan Leavengood BRect frame = screen.Frame(); 6644f919daSRyan Leavengood BRect image = fImage->Bounds(); 6744f919daSRyan Leavengood 68*091440e0SStephan Aßmus if (image.Width() > (frame.Width() - 100.0f)) 6944f919daSRyan Leavengood image.right = frame.Width() - 100.0f; 70*091440e0SStephan Aßmus if (image.Height() > (frame.Height() - 100.0f)) 7144f919daSRyan Leavengood image.bottom = frame.Height() - 100.f; 7244f919daSRyan Leavengood 7344f919daSRyan Leavengood ResizeTo(image.Width(), image.Height()); 7444f919daSRyan Leavengood } 7544f919daSRyan Leavengood 7644f919daSRyan Leavengood 7744f919daSRyan Leavengood void 7844f919daSRyan Leavengood ImageView::Draw(BRect updateRect) 7944f919daSRyan Leavengood { 8044f919daSRyan Leavengood if (fSuccess) 8144f919daSRyan Leavengood DrawBitmapAsync(fImage, Bounds()); 8244f919daSRyan Leavengood else { 83*091440e0SStephan Aßmus float length = StringWidth(TR("Image not loaded correctly")); 84*091440e0SStephan Aßmus DrawString(TR("Image not loaded correctly"), 8544f919daSRyan Leavengood BPoint((Bounds().Width() - length) / 2.0f, 30.0f)); 8644f919daSRyan Leavengood } 8744f919daSRyan Leavengood } 8844f919daSRyan Leavengood 8944f919daSRyan Leavengood 9044f919daSRyan Leavengood void 9144f919daSRyan Leavengood ImageView::MouseUp(BPoint point) 9244f919daSRyan Leavengood { 9344f919daSRyan Leavengood BWindow *parent = Window(); 9444f919daSRyan Leavengood if (parent) 9544f919daSRyan Leavengood parent->PostMessage(P_MSG_CLOSE); 9644f919daSRyan Leavengood } 9744f919daSRyan Leavengood 9844f919daSRyan Leavengood 9944f919daSRyan Leavengood // #pragma mark - 10044f919daSRyan Leavengood 10144f919daSRyan Leavengood 10244f919daSRyan Leavengood PackageImageViewer::PackageImageViewer(BPositionIO *image) 103*091440e0SStephan Aßmus : 104*091440e0SStephan Aßmus BWindow(BRect(100, 100, 100, 100), "", B_MODAL_WINDOW, 10544f919daSRyan Leavengood B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_NOT_CLOSABLE) 10644f919daSRyan Leavengood { 10744f919daSRyan Leavengood fBackground = new ImageView(image); 10844f919daSRyan Leavengood AddChild(fBackground); 10944f919daSRyan Leavengood 11044f919daSRyan Leavengood ResizeTo(fBackground->Bounds().Width(), fBackground->Bounds().Height()); 11144f919daSRyan Leavengood 11244f919daSRyan Leavengood BScreen screen(this); 11344f919daSRyan Leavengood BRect frame = screen.Frame(); 11444f919daSRyan Leavengood MoveTo((frame.Width() - Bounds().Width()) / 2.0f, 11544f919daSRyan Leavengood (frame.Height() - Bounds().Height()) / 2.0f); 11644f919daSRyan Leavengood } 11744f919daSRyan Leavengood 11844f919daSRyan Leavengood 11944f919daSRyan Leavengood PackageImageViewer::~PackageImageViewer() 12044f919daSRyan Leavengood { 12144f919daSRyan Leavengood } 12244f919daSRyan Leavengood 12344f919daSRyan Leavengood 12444f919daSRyan Leavengood void 12544f919daSRyan Leavengood PackageImageViewer::Go() 12644f919daSRyan Leavengood { 12744f919daSRyan Leavengood // Since this class can be thought of as a modified BAlert window, no use 12844f919daSRyan Leavengood // to reinvent a well fledged wheel. This concept has been borrowed from 12944f919daSRyan Leavengood // the current BAlert implementation 13044f919daSRyan Leavengood fSemaphore = create_sem(0, "ImageViewer"); 13144f919daSRyan Leavengood if (fSemaphore < B_OK) { 13244f919daSRyan Leavengood Quit(); 13344f919daSRyan Leavengood return; 13444f919daSRyan Leavengood } 13544f919daSRyan Leavengood 13644f919daSRyan Leavengood BWindow *parent = 13744f919daSRyan Leavengood dynamic_cast<BWindow *>(BLooper::LooperForThread(find_thread(NULL))); 13844f919daSRyan Leavengood Show(); 13944f919daSRyan Leavengood 14044f919daSRyan Leavengood if (parent) { 14144f919daSRyan Leavengood status_t ret; 14244f919daSRyan Leavengood for (;;) { 14344f919daSRyan Leavengood do { 14444f919daSRyan Leavengood ret = acquire_sem_etc(fSemaphore, 1, B_RELATIVE_TIMEOUT, 50000); 14544f919daSRyan Leavengood } while (ret == B_INTERRUPTED); 14644f919daSRyan Leavengood 14744f919daSRyan Leavengood if (ret == B_BAD_SEM_ID) 14844f919daSRyan Leavengood break; 14944f919daSRyan Leavengood parent->UpdateIfNeeded(); 15044f919daSRyan Leavengood } 15144f919daSRyan Leavengood } 15244f919daSRyan Leavengood else { 15344f919daSRyan Leavengood // Since there are no spinlocks, wait until the semaphore is free 15444f919daSRyan Leavengood while (acquire_sem(fSemaphore) == B_INTERRUPTED) { 15544f919daSRyan Leavengood } 15644f919daSRyan Leavengood } 15744f919daSRyan Leavengood 15844f919daSRyan Leavengood if (Lock()) 15944f919daSRyan Leavengood Quit(); 16044f919daSRyan Leavengood } 16144f919daSRyan Leavengood 16244f919daSRyan Leavengood 16344f919daSRyan Leavengood void 16444f919daSRyan Leavengood PackageImageViewer::MessageReceived(BMessage *msg) 16544f919daSRyan Leavengood { 16644f919daSRyan Leavengood if (msg->what == P_MSG_CLOSE) { 16744f919daSRyan Leavengood if (fSemaphore >= B_OK) { 16844f919daSRyan Leavengood delete_sem(fSemaphore); 16944f919daSRyan Leavengood fSemaphore = -1; 17044f919daSRyan Leavengood } 171*091440e0SStephan Aßmus } else 17244f919daSRyan Leavengood BWindow::MessageReceived(msg); 17344f919daSRyan Leavengood } 17444f919daSRyan Leavengood 175