haiku/src/apps/packageinstaller/PackageImageViewer.cpp
Ryan Leavengood 44f919da9a Adding Łukasz Zemczak's package installer to our tree. This was his Google
Summer of Code project. Thanks for your work Łukasz and I hope we can see
more work from you.

Still to do:
- Create an icon.
- Add pkg files to the MIME database with PackageInstaller as the default
handler. The rdef here has the MIME type name for the pkg format should
anyone else choose to add it :)
- Support for running scripts included with packages.
- Testing various different packages.
- Fixing problems in the Haiku GUI layout system which affect the code used 
for various parts of the installer GUI (please bear with the commented out
code for now.)
- Adding this to the image.

Tomorrow I will add Łukasz's InstalledPackages utility which can be used to
view installed packages and uninstall them.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22525 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-10-13 04:46:32 +00:00

176 lines
3.2 KiB
C++

/*
* Copyright (c) 2007, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Author:
* Łukasz 'Sil2100' Zemczak <sil2100@vexillium.org>
*/
#include "PackageImageViewer.h"
#include <BitmapStream.h>
#include <Message.h>
#include <Screen.h>
#include <TranslatorRoster.h>
// Reserved
#define T(x) x
enum {
P_MSG_CLOSE = 'pmic'
};
ImageView::ImageView(BPositionIO *image)
: BView(BRect(0, 0, 1, 1), "image_view", B_FOLLOW_NONE, B_WILL_DRAW),
fSuccess(true)
{
if (!image) {
fSuccess = false;
return;
}
// Initialize and translate the image
BTranslatorRoster *roster = BTranslatorRoster::Default();
BBitmapStream stream;
if (roster->Translate(image, NULL, NULL, &stream, B_TRANSLATOR_BITMAP)
< B_OK) {
fSuccess = false;
return;
}
stream.DetachBitmap(&fImage);
}
ImageView::~ImageView()
{
}
void
ImageView::AttachedToWindow()
{
if (!fSuccess) {
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 (fSuccess)
DrawBitmapAsync(fImage, Bounds());
else {
float length = StringWidth(T("Image not loaded correctly"));
DrawString(T("Image not loaded correctly"),
BPoint((Bounds().Width() - length) / 2.0f, 30.0f));
}
}
void
ImageView::MouseUp(BPoint point)
{
BWindow *parent = Window();
if (parent)
parent->PostMessage(P_MSG_CLOSE);
}
// #pragma mark -
PackageImageViewer::PackageImageViewer(BPositionIO *image)
: BWindow(BRect(100, 100, 100, 100), "", B_MODAL_WINDOW,
B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_NOT_CLOSABLE)
{
fBackground = new ImageView(image);
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()
{
}
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;
}
BWindow *parent =
dynamic_cast<BWindow *>(BLooper::LooperForThread(find_thread(NULL)));
Show();
if (parent) {
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;
parent->UpdateIfNeeded();
}
}
else {
// Since there are no spinlocks, wait until the semaphore is free
while (acquire_sem(fSemaphore) == B_INTERRUPTED) {
}
}
if (Lock())
Quit();
}
void
PackageImageViewer::MessageReceived(BMessage *msg)
{
if (msg->what == P_MSG_CLOSE) {
if (fSemaphore >= B_OK) {
delete_sem(fSemaphore);
fSemaphore = -1;
}
}
else
BWindow::MessageReceived(msg);
}