PackageInstaller: Converted to use layout API

* Also auto-hide vertical scroll-bars when not needed.
 * Nicer margins everywhere
 * TODO: Install type description could collapse when empty or display
   a default message.
 * More refactoring and cleanup
This commit is contained in:
Stephan Aßmus
2014-02-16 12:12:25 +01:00
parent a16a1437a7
commit 735727da48
3 changed files with 130 additions and 162 deletions
+117 -153
View File
@@ -4,6 +4,7 @@
* *
* Author: * Author:
* Łukasz 'Sil2100' Zemczak <[email protected]> * Łukasz 'Sil2100' Zemczak <[email protected]>
* Stephan Aßmus <[email protected]>
*/ */
@@ -20,6 +21,7 @@
#include <FilePanel.h> #include <FilePanel.h>
#include <FindDirectory.h> #include <FindDirectory.h>
#include <Locale.h> #include <Locale.h>
#include <LayoutBuilder.h>
#include <MenuField.h> #include <MenuField.h>
#include <MenuItem.h> #include <MenuItem.h>
#include <Path.h> #include <Path.h>
@@ -66,9 +68,9 @@ convert_size(uint64 size, char *buffer, uint32 n)
// #pragma mark - // #pragma mark -
PackageView::PackageView(BRect frame, const entry_ref *ref) PackageView::PackageView(const entry_ref* ref)
: :
BView(frame, "package_view", B_FOLLOW_NONE, 0), BView("package_view", 0),
fOpenPanel(new BFilePanel(B_OPEN_PANEL, NULL, NULL, B_DIRECTORY_NODE, fOpenPanel(new BFilePanel(B_OPEN_PANEL, NULL, NULL, B_DIRECTORY_NODE,
false)), false)),
fInfo(ref), fInfo(ref),
@@ -80,8 +82,6 @@ PackageView::PackageView(BRect frame, const entry_ref *ref)
status_t ret = fInfo.InitCheck(); status_t ret = fInfo.InitCheck();
if (ret == B_OK) if (ret == B_OK)
_InitProfiles(); _InitProfiles();
ResizeTo(Bounds().Width(), fInstall->Frame().bottom + 4);
} }
@@ -96,7 +96,7 @@ PackageView::AttachedToWindow()
{ {
status_t ret = fInfo.InitCheck(); status_t ret = fInfo.InitCheck();
if (ret != B_OK && ret != B_NO_INIT) { if (ret != B_OK && ret != B_NO_INIT) {
BAlert *warning = new BAlert("parsing_failed", BAlert* warning = new BAlert("parsing_failed",
B_TRANSLATE("The package file is not readable.\nOne of the " B_TRANSLATE("The package file is not readable.\nOne of the "
"possible reasons for this might be that the requested file " "possible reasons for this might be that the requested file "
"is not a valid BeOS .pkg package."), B_TRANSLATE("OK"), "is not a valid BeOS .pkg package."), B_TRANSLATE("OK"),
@@ -109,13 +109,12 @@ PackageView::AttachedToWindow()
} }
// Set the window title // Set the window title
BWindow *parent = Window(); BWindow* parent = Window();
BString title; BString title;
BString name = fInfo.GetName(); BString name = fInfo.GetName();
if (name.CountChars() == 0) { if (name.CountChars() == 0) {
title = B_TRANSLATE("Package installer"); title = B_TRANSLATE("Package installer");
} } else {
else {
title = B_TRANSLATE("Install %name%"); title = B_TRANSLATE("Install %name%");
title.ReplaceAll("%name%", name); title.ReplaceAll("%name%", name);
} }
@@ -131,7 +130,7 @@ PackageView::AttachedToWindow()
// If the package is valid, we can set up the default group and all // If the package is valid, we can set up the default group and all
// other things. If not, then the application will close just after // other things. If not, then the application will close just after
// attaching the view to the window // attaching the view to the window
_GroupChanged(0); _InstallTypeChanged(0);
fStatusWindow = new PackageStatus(B_TRANSLATE("Installation progress"), fStatusWindow = new PackageStatus(B_TRANSLATE("Installation progress"),
NULL, NULL, this); NULL, NULL, this);
@@ -174,25 +173,23 @@ PackageView::MessageReceived(BMessage* message)
case P_MSG_PATH_CHANGED: case P_MSG_PATH_CHANGED:
{ {
BString path; BString path;
if (message->FindString("path", &path) == B_OK) { if (message->FindString("path", &path) == B_OK)
fCurrentPath.SetTo(path.String()); fCurrentPath.SetTo(path.String());
}
break; break;
} }
case P_MSG_OPEN_PANEL: case P_MSG_OPEN_PANEL:
fOpenPanel->Show(); fOpenPanel->Show();
break; break;
case P_MSG_GROUP_CHANGED: case P_MSG_INSTALL_TYPE_CHANGED:
{ {
int32 index; int32 index;
if (message->FindInt32("index", &index) == B_OK) { if (message->FindInt32("index", &index) == B_OK)
_GroupChanged(index); _InstallTypeChanged(index);
}
break; break;
} }
case P_MSG_I_FINISHED: case P_MSG_I_FINISHED:
{ {
BAlert *notify = new BAlert("installation_success", BAlert* notify = new BAlert("installation_success",
B_TRANSLATE("The package you requested has been successfully " B_TRANSLATE("The package you requested has been successfully "
"installed on your system."), "installed on your system."),
B_TRANSLATE("OK")); B_TRANSLATE("OK"));
@@ -212,7 +209,7 @@ PackageView::MessageReceived(BMessage* message)
} }
case P_MSG_I_ABORT: case P_MSG_I_ABORT:
{ {
BAlert *notify = new BAlert("installation_aborted", BAlert* notify = new BAlert("installation_aborted",
B_TRANSLATE( B_TRANSLATE(
"The installation of the package has been aborted."), "The installation of the package has been aborted."),
B_TRANSLATE("OK")); B_TRANSLATE("OK"));
@@ -228,7 +225,7 @@ PackageView::MessageReceived(BMessage* message)
case P_MSG_I_ERROR: case P_MSG_I_ERROR:
{ {
// TODO: Review this // TODO: Review this
BAlert *notify = new BAlert("installation_failed", BAlert* notify = new BAlert("installation_failed",
B_TRANSLATE("The requested package failed to install on your " B_TRANSLATE("The requested package failed to install on your "
"system. This might be a problem with the target package " "system. This might be a problem with the target package "
"file. Please consult this issue with the package " "file. Please consult this issue with the package "
@@ -264,20 +261,18 @@ PackageView::MessageReceived(BMessage* message)
entry_ref ref; entry_ref ref;
if (message->FindRef("refs", &ref) == B_OK) { if (message->FindRef("refs", &ref) == B_OK) {
BPath path(&ref); BPath path(&ref);
if (path.InitCheck() != B_OK)
break;
BMenuItem* item = fDestField->MenuItem();
dev_t device = dev_for_path(path.Path()); dev_t device = dev_for_path(path.Path());
BVolume volume(device); BVolume volume(device);
if (volume.InitCheck() != B_OK) if (volume.InitCheck() != B_OK)
break; break;
BString name = path.Path(); BMenuItem* item = fDestField->MenuItem();
char sizeString[48];
convert_size(volume.FreeBytes(), sizeString, 48); BString name = _NamePlusSizeString(path.Path(),
char buffer[512]; volume.FreeBytes(), B_TRANSLATE("%name% (%size% free)"));
snprintf(buffer, sizeof(buffer), "(%s free)", sizeString);
name << buffer;
item->SetLabel(name.String()); item->SetLabel(name.String());
fCurrentPath.SetTo(path.Path()); fCurrentPath.SetTo(path.Path());
@@ -354,7 +349,7 @@ PackageView::ItemExists(PackageItem& item, BPath& path, int32& policy)
BString alertString = buffer; BString alertString = buffer;
BAlert *alert = new BAlert("file_exists", alertString.String(), BAlert* alert = new BAlert("file_exists", alertString.String(),
B_TRANSLATE("Replace"), B_TRANSLATE("Replace"),
B_TRANSLATE("Skip"), B_TRANSLATE("Skip"),
B_TRANSLATE("Abort")); B_TRANSLATE("Abort"));
@@ -404,147 +399,116 @@ PackageView::ItemExists(PackageItem& item, BPath& path, int32& policy)
} }
/* // #pragma mark -
class DescriptionTextView : public BTextView {
public:
DescriptionTextView(const char* name, float minHeight)
:
BTextView(name)
{
SetExplicitMinSize(BSize(B_SIZE_UNSET, minHeight));
}
virtual void AttachedToWindow()
{
BTextView::AttachedToWindow();
_UpdateScrollBarVisibility();
}
virtual void FrameResized(float width, float height)
{
BTextView::FrameResized(width, height);
_UpdateScrollBarVisibility();
}
virtual void Draw(BRect updateRect)
{
BTextView::Draw(updateRect);
_UpdateScrollBarVisibility();
}
private:
void _UpdateScrollBarVisibility()
{
BScrollBar* verticalBar = ScrollBar(B_VERTICAL);
if (verticalBar != NULL) {
float min;
float max;
verticalBar->GetRange(&min, &max);
if (min == max) {
if (!verticalBar->IsHidden(verticalBar))
verticalBar->Hide();
} else {
if (verticalBar->IsHidden(verticalBar))
verticalBar->Show();
}
}
}
};
void void
PackageView::_InitView() PackageView::_InitView()
{ {
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BTextView *description = new BTextView(BRect(0, 0, 20, 20), "description", float fontHeight = be_plain_font->Size();
BRect(4, 4, 16, 16), B_FOLLOW_NONE, B_WILL_DRAW);
description->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
description->SetText(fInfo.GetDescription());
description->MakeEditable(false);
description->MakeSelectable(false);
BTextView* packageDescriptionView = new DescriptionTextView(
"package description", fontHeight * 13);
packageDescriptionView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
packageDescriptionView->SetText(fInfo.GetDescription());
packageDescriptionView->MakeEditable(false);
packageDescriptionView->MakeSelectable(false);
BScrollView* descriptionScrollView = new BScrollView(
"package description scroll view", packageDescriptionView,
0, false, true, B_NO_BORDER);
// Install type menu field
fInstallTypes = new BPopUpMenu(B_TRANSLATE("none")); fInstallTypes = new BPopUpMenu(B_TRANSLATE("none"));
BMenuField* installType = new BMenuField("install_type",
B_TRANSLATE("Installation type:"), fInstallTypes);
BMenuField *installType = new BMenuField("install_type", // Install type description text view
B_TRANSLATE("Installation type:"), fInstallTypes, 0); fInstallTypeDescriptionView = new DescriptionTextView(
installType->SetAlignment(B_ALIGN_RIGHT); "install type description", fontHeight * 3);
installType->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); fInstallTypeDescriptionView->MakeEditable(false);
fInstallTypeDescriptionView->MakeSelectable(false);
fInstallTypeDescriptionView->SetText(
B_TRANSLATE("No installation type selected"));
fInstallTypeDescriptionView->SetViewColor(
ui_color(B_PANEL_BACKGROUND_COLOR));
fInstallDesc = new BTextView(BRect(0, 0, 10, 10), "install_desc", BScrollView* installTypeScrollView = new BScrollView(
BRect(2, 2, 8, 8), B_FOLLOW_NONE, B_WILL_DRAW); "install type description scroll view", fInstallTypeDescriptionView,
fInstallDesc->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 0, false, true, B_NO_BORDER);
fInstallDesc->MakeEditable(false);
fInstallDesc->MakeSelectable(false); // Destination menu field
fInstallDesc->SetText(B_TRANSLATE("No installation type selected")); fDestination = new BPopUpMenu(B_TRANSLATE("none"));
fInstallDesc->TextHeight(0, fInstallDesc->TextLength()); fDestField = new BMenuField("install_to", B_TRANSLATE("Install to:"),
fDestination);
fInstall = new BButton("install_button", B_TRANSLATE("Install"), fInstall = new BButton("install_button", B_TRANSLATE("Install"),
new BMessage(P_MSG_INSTALL)); new BMessage(P_MSG_INSTALL));
BView *installField = BGroupLayoutBuilder(B_VERTICAL, 5.0f) // Build the layout
.AddGroup(B_HORIZONTAL) BLayoutBuilder::Group<>(this, B_VERTICAL)
.Add(installType) .Add(descriptionScrollView)
.AddGlue() .AddGrid()
.AddMenuField(fDestField, 0, 0, B_ALIGN_RIGHT)
.AddMenuField(installType, 0, 1, B_ALIGN_RIGHT)
.Add(installTypeScrollView, 0, 2, 2)
.End() .End()
.Add(fInstallDesc);
BBox *installBox = new BBox("install_box");
installBox->AddChild(installField);
BView *root = BGroupLayoutBuilder(B_VERTICAL, 3.0f)
.Add(description)
.Add(installBox)
.AddGroup(B_HORIZONTAL) .AddGroup(B_HORIZONTAL)
.AddGlue() .AddGlue()
.Add(fInstall) .Add(fInstall)
.End(); .End()
.SetInsets(B_USE_DEFAULT_SPACING)
;
AddChild(root);
fInstall->MakeDefault(true);
}*/
void
PackageView::_InitView()
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BRect rect = Bounds();
BTextView *description = new BTextView(rect, "description",
rect.InsetByCopy(5, 5), B_FOLLOW_NONE, B_WILL_DRAW);
description->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
description->SetText(fInfo.GetDescription());
description->MakeEditable(false);
description->MakeSelectable(false);
float length = description->TextHeight(0, description->TextLength()) + 5;
if (length > kMaxDescHeight) {
// Set a scroller for the description.
description->ResizeTo(rect.Width() - B_V_SCROLL_BAR_WIDTH,
kMaxDescHeight);
BScrollView *scroller = new BScrollView("desciption_view", description,
B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS, false, true,
B_NO_BORDER);
AddChild(scroller);
rect = scroller->Frame();
}
else {
description->ResizeTo(rect.Width(), length);
AddChild(description);
rect = description->Frame();
}
rect.top = rect.bottom + 2;
rect.bottom += 100;
BBox *installBox = new BBox(rect.InsetByCopy(2, 2), "install_box");
fInstallTypes = new BPopUpMenu(B_TRANSLATE("none"));
BMenuField *installType = new BMenuField(BRect(2, 2, 100, 50),
"install_type", B_TRANSLATE("Installation type:"),
fInstallTypes, false);
installType->SetDivider(installType->StringWidth(installType->Label()) + 8);
installType->SetAlignment(B_ALIGN_RIGHT);
installType->ResizeToPreferred();
installBox->AddChild(installType);
rect = installBox->Bounds().InsetBySelf(4, 4);
rect.top = installType->Frame().bottom;
fInstallDesc = new BTextView(rect, "install_desc",
BRect(2, 2, rect.Width() - 2, rect.Height() - 2), B_FOLLOW_NONE,
B_WILL_DRAW);
fInstallDesc->MakeEditable(false);
fInstallDesc->MakeSelectable(false);
fInstallDesc->SetText(B_TRANSLATE("No installation type selected"));
fInstallDesc->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fInstallDesc->ResizeTo(rect.Width() - B_V_SCROLL_BAR_WIDTH, 60);
BScrollView *scroller = new BScrollView("desciption_view", fInstallDesc,
B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS, false, true, B_NO_BORDER);
installBox->ResizeTo(installBox->Bounds().Width(),
scroller->Frame().bottom + 10);
installBox->AddChild(scroller);
AddChild(installBox);
fDestination = new BPopUpMenu(B_TRANSLATE("none"));
rect = installBox->Frame();
rect.top = rect.bottom + 5;
rect.bottom += 35;
fDestField = new BMenuField(rect, "install_to", B_TRANSLATE("Install to:"),
fDestination, false);
fDestField->SetDivider(fDestField->StringWidth(fDestField->Label()) + 8);
fDestField->SetAlignment(B_ALIGN_RIGHT);
fDestField->ResizeToPreferred();
AddChild(fDestField);
fInstall = new BButton(rect, "install_button", B_TRANSLATE("Install"),
new BMessage(P_MSG_INSTALL));
fInstall->ResizeToPreferred();
AddChild(fInstall);
fInstall->MoveTo(Bounds().Width() - fInstall->Bounds().Width() - 10,
rect.top + 2);
fInstall->MakeDefault(true); fInstall->MakeDefault(true);
} }
@@ -575,7 +539,7 @@ PackageView::_InitProfiles()
status_t status_t
PackageView::_GroupChanged(int32 index) PackageView::_InstallTypeChanged(int32 index)
{ {
if (index < 0) if (index < 0)
return B_ERROR; return B_ERROR;
@@ -592,7 +556,7 @@ PackageView::_GroupChanged(int32 index)
if (profile == NULL) if (profile == NULL)
return B_ERROR; return B_ERROR;
fInstallDesc->SetText(profile->description.String()); fInstallTypeDescriptionView->SetText(profile->description.String());
BPath path; BPath path;
BVolume volume; BVolume volume;
@@ -682,7 +646,7 @@ PackageView::_AddInstallTypeMenuItem(BString baseName, size_t size,
BString name = _NamePlusSizeString(baseName, size, BString name = _NamePlusSizeString(baseName, size,
B_TRANSLATE("%name% (%size%)")); B_TRANSLATE("%name% (%size%)"));
BMessage* message = new BMessage(P_MSG_GROUP_CHANGED); BMessage* message = new BMessage(P_MSG_INSTALL_TYPE_CHANGED);
message->AddInt32("index", index); message->AddInt32("index", index);
return _AddMenuItem(name, message, fInstallTypes); return _AddMenuItem(name, message, fInstallTypes);
+4 -4
View File
@@ -25,7 +25,7 @@ class BTextView;
enum { enum {
P_MSG_GROUP_CHANGED = 'gpch', P_MSG_INSTALL_TYPE_CHANGED = 'gpch',
P_MSG_PATH_CHANGED, P_MSG_PATH_CHANGED,
P_MSG_OPEN_PANEL, P_MSG_OPEN_PANEL,
P_MSG_INSTALL P_MSG_INSTALL
@@ -33,7 +33,7 @@ enum {
class PackageView : public BView { class PackageView : public BView {
public: public:
PackageView(BRect frame, const entry_ref* ref); PackageView(const entry_ref* ref);
virtual ~PackageView(); virtual ~PackageView();
virtual void AttachedToWindow(); virtual void AttachedToWindow();
@@ -55,7 +55,7 @@ private:
void _InitView(); void _InitView();
void _InitProfiles(); void _InitProfiles();
status_t _GroupChanged(int32 index); status_t _InstallTypeChanged(int32 index);
BString _NamePlusSizeString(BString name, BString _NamePlusSizeString(BString name,
size_t size, const char* format) const; size_t size, const char* format) const;
@@ -68,7 +68,7 @@ private:
private: private:
BPopUpMenu* fInstallTypes; BPopUpMenu* fInstallTypes;
BTextView* fInstallDesc; BTextView* fInstallTypeDescriptionView;
BPopUpMenu* fDestination; BPopUpMenu* fDestination;
BMenuField* fDestField; BMenuField* fDestField;
BButton* fInstall; BButton* fInstall;
+9 -5
View File
@@ -1,9 +1,10 @@
/* /*
* Copyright (c) 2007-2010, Haiku, Inc. All rights reserved. * Copyright (c) 2007-2014, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT license. * Distributed under the terms of the MIT license.
* *
* Author: * Author:
* Łukasz 'Sil2100' Zemczak <[email protected]> * Łukasz 'Sil2100' Zemczak <[email protected]>
* Stephan Aßmus <[email protected]>
*/ */
@@ -11,6 +12,7 @@
#include <Application.h> #include <Application.h>
#include <Catalog.h> #include <Catalog.h>
#include <LayoutBuilder.h>
#include "PackageView.h" #include "PackageView.h"
@@ -23,12 +25,14 @@ PackageWindow::PackageWindow(const entry_ref* ref)
: :
BWindow(BRect(100, 100, 600, 300), BWindow(BRect(100, 100, 600, 300),
B_TRANSLATE_SYSTEM_NAME("PackageInstaller"), B_TRANSLATE_SYSTEM_NAME("PackageInstaller"),
B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_NOT_RESIZABLE) B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS)
{ {
PackageView* view = new PackageView(Bounds(), ref); PackageView* view = new PackageView(ref);
AddChild(view);
BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f)
.Add(view)
;
ResizeTo(Bounds().Width(), view->Bounds().Height());
CenterOnScreen(); CenterOnScreen();
} }