SoftwareUpdater- add zoom feature and bug fix

* Added zoom button to window tab (and backend code to accurately
  calculate proper zoom size for displayed packages)
* No longer need to add icon to notifications since this is now done
  automatically by the BNotification constructor since hrev51299
* Create icons and setup fonts in constructors of list item classes

Bug fixes:
* Lock windows before quitting (fixes #13613)
This commit is contained in:
Brian Hill
2017-07-30 21:57:20 -04:00
parent 70dde0b360
commit 17683fa9b6
7 changed files with 247 additions and 117 deletions
-17
View File
@@ -308,22 +308,5 @@ CheckManager::_SendNotification(const char* title, const char* text)
notification.SetOnClickApp(kAppSignature);
if(fVerbose)
notification.SetMessageID(fNotificationId);
BBitmap icon(_GetIcon());
if (icon.IsValid())
notification.SetIcon(&icon);
notification.Send();
}
BBitmap
CheckManager::_GetIcon()
{
int32 iconSize = B_LARGE_ICON;
BBitmap icon(BRect(0, 0, iconSize - 1, iconSize - 1), 0, B_RGBA32);
team_info teamInfo;
get_team_info(B_CURRENT_TEAM, &teamInfo);
app_info appInfo;
be_roster->GetRunningAppInfo(teamInfo.team, &appInfo);
BNodeInfo::GetTrackerIcon(&appInfo.ref, &icon, icon_size(iconSize));
return icon;
}
-1
View File
@@ -64,7 +64,6 @@ private:
int32& updateCount);
void _SendNotification(const char* title,
const char* text);
BBitmap _GetIcon();
private:
BPackageManager::ClientInstallationInterface
@@ -5,7 +5,7 @@ resource app_flags B_SINGLE_LAUNCH;
resource app_version {
major = 1,
middle = 0,
minor = 2,
minor = 3,
variety = B_APPV_BETA,
internal = 0,
short_info = "SoftwareUpdater",
@@ -150,6 +150,15 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
fCancelAlertResponse.SetTarget(this);
fWarningAlertDismissed.SetMessage(new BMessage(kMsgWarningDismissed));
fWarningAlertDismissed.SetTarget(this);
// Common elements used for the zoom height and width calculations
fZoomHeightBaseline = 6
+ be_control_look->ComposeSpacing(B_USE_SMALL_SPACING)
+ 2 * be_control_look->ComposeSpacing(B_USE_WINDOW_SPACING);
fZoomWidthBaseline = fStripeView->PreferredSize().Width()
+ be_control_look->ComposeSpacing(B_USE_ITEM_SPACING)
+ fScrollView->ScrollBar(B_VERTICAL)->PreferredSize().Width()
+ be_control_look->ComposeSpacing(B_USE_WINDOW_SPACING);
}
@@ -195,6 +204,15 @@ SoftwareUpdaterWindow::FrameResized(float newWidth, float newHeight)
}
void
SoftwareUpdaterWindow::Zoom(BPoint origin, float width, float height)
{
// Override default zoom behavior and keep window at same position instead
// of centering on screen
BWindow::Zoom(Frame().LeftTop(), width, height);
}
void
SoftwareUpdaterWindow::MessageReceived(BMessage* message)
{
@@ -324,9 +342,32 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
case kMsgMoreDetailsToggle:
fListView->SetMoreDetails(fDetailsCheckbox->Value() != 0);
PostMessage(kMsgSetZoomLimits);
_WriteSettings();
break;
case kMsgSetZoomLimits:
{
int32 count = fListView->CountItems();
if (count < 1)
break;
// Convert last item's bottom point to its layout group coordinates
BPoint zoomPoint = fListView->ZoomPoint();
fScrollView->ConvertToParent(&zoomPoint);
// Determine which BControl object height to use
float controlHeight;
if (fUpdateButtonLayoutItem->IsVisible())
fUpdateButton->GetPreferredSize(NULL, &controlHeight);
else
fDetailsCheckbox->GetPreferredSize(NULL, &controlHeight);
// Calculate height and width values
float zoomHeight = fZoomHeightBaseline + zoomPoint.y
+ controlHeight;
float zoomWidth = fZoomWidthBaseline + zoomPoint.x;
SetZoomLimits(zoomWidth, zoomHeight);
break;
}
case kMsgWarningDismissed:
fWarningAlertCount--;
break;
@@ -474,13 +515,6 @@ SoftwareUpdaterWindow::GetIcon(int32 iconSize)
}
BBitmap
SoftwareUpdaterWindow::GetNotificationIcon()
{
return GetIcon(B_LARGE_ICON);
}
void
SoftwareUpdaterWindow::FinalUpdate(const char* header, const char* detail)
{
@@ -570,14 +604,15 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
fDetailsLayoutItem->SetVisible(true);
}
// Resizing
// Resizing and zooming
if (fCurrentState == STATE_GET_CONFIRMATION) {
// Enable resizing
// Enable resizing and zooming
float defaultWidth = fDefaultRect.Width();
SetSizeLimits(defaultWidth, B_SIZE_UNLIMITED,
fDefaultRect.Height() + 4 * fListView->ItemHeight(),
B_SIZE_UNLIMITED);
SetFlags(Flags() ^ B_NOT_RESIZABLE);
SetFlags(Flags() ^ (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
PostMessage(kMsgSetZoomLimits);
// Recall saved settings
BScreen screen(this);
BRect screenFrame = screen.Frame();
@@ -601,13 +636,17 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
if (windowBottom > screenBottom)
MoveBy(0, screenBottom - windowBottom);
fSaveFrameChanges = true;
} else if (fUpdateConfirmed && (fCurrentState == STATE_DISPLAY_PROGRESS
|| fCurrentState == STATE_DISPLAY_STATUS)) {
PostMessage(kMsgSetZoomLimits);
} else if (fCurrentState == STATE_APPLY_UPDATES)
fSaveFrameChanges = false;
else if (fCurrentState == STATE_FINAL_MESSAGE) {
// Disable resizing
// Disable resizing and zooming
fSaveFrameChanges = false;
ResizeTo(fDefaultRect.Width(), fDefaultRect.Height());
SetFlags(Flags() | B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_RESIZABLE);
SetFlags(Flags() | B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_RESIZABLE
| B_NOT_ZOOMABLE);
}
// Quit button
@@ -661,16 +700,28 @@ SuperItem::SuperItem(const char* label)
:
BListItem(),
fLabel(label),
fRegularFont(be_plain_font),
fBoldFont(be_plain_font),
fShowMoreDetails(false),
fPackageIcon(NULL),
fPackageLessIcon(NULL),
fPackageMoreIcon(NULL),
fItemCount(0)
{
fBoldFont.SetFace(B_BOLD_FACE);
fBoldFont.GetHeight(&fBoldFontHeight);
font_height fontHeight;
fRegularFont.GetHeight(&fontHeight);
fPackageItemLineHeight = fontHeight.ascent + fontHeight.descent
+ fontHeight.leading;
fPackageLessIcon = _GetPackageIcon(GetPackageItemHeight(false));
fPackageMoreIcon = _GetPackageIcon(GetPackageItemHeight(true));
}
SuperItem::~SuperItem()
{
delete fPackageIcon;
delete fPackageLessIcon;
delete fPackageMoreIcon;
}
@@ -680,29 +731,50 @@ SuperItem::DrawItem(BView* owner, BRect item_rect, bool complete)
owner->PushState();
float width;
owner->GetPreferredSize(&width, NULL);
BString label(fLabel);
label.Append(" (");
label << fItemCount;
label.Append(")");
owner->TruncateString(&label, B_TRUNCATE_END, width);
owner->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR));
owner->SetFont(&fBoldFont);
owner->DrawString(label.String(), BPoint(item_rect.left,
item_rect.bottom - fFontHeight.descent - 1));
owner->GetPreferredSize(&width, NULL);
BString text(fItemText);
owner->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR));
owner->SetFont(&fBoldFont);
owner->TruncateString(&text, B_TRUNCATE_END, width);
owner->DrawString(text.String(), BPoint(item_rect.left,
item_rect.bottom - fBoldFontHeight.descent));
owner->PopState();
}
void
SuperItem::Update(BView *owner, const BFont *font)
float
SuperItem::GetPackageItemHeight()
{
fRegularFont = *font;
fBoldFont = *font;
fBoldFont.SetFace(B_BOLD_FACE);
BListItem::Update(owner, &fBoldFont);
_SetHeights();
return GetPackageItemHeight(fShowMoreDetails);
}
float
SuperItem::GetPackageItemHeight(bool showMoreDetails)
{
int lineCount = showMoreDetails ? 3 : 2;
return lineCount * fPackageItemLineHeight;
}
BBitmap*
SuperItem::GetIcon(bool showMoreDetails)
{
if (showMoreDetails)
return fPackageMoreIcon;
else
return fPackageLessIcon;
}
float
SuperItem::GetIconSize(bool showMoreDetails)
{
if (showMoreDetails)
return fPackageMoreIcon->Bounds().Height();
else
return fPackageLessIcon->Bounds().Height();
}
@@ -710,50 +782,52 @@ void
SuperItem::SetDetailLevel(bool showMoreDetails)
{
fShowMoreDetails = showMoreDetails;
_SetHeights();
}
void
SuperItem::_SetHeights()
SuperItem::SetItemCount(int32 count)
{
// Calculate height for PackageItem
fRegularFont.GetHeight(&fFontHeight);
int lineCount = fShowMoreDetails ? 3 : 2;
fPackageItemHeight = lineCount * (fFontHeight.ascent + fFontHeight.descent
+ fFontHeight.leading);
// Calculate height for this item
fBoldFont.GetHeight(&fFontHeight);
SetHeight(fFontHeight.ascent + fFontHeight.descent
+ fFontHeight.leading + 4);
_GetPackageIcon();
fItemCount = count;
fItemText = fLabel;
fItemText.Append(" (");
fItemText << fItemCount;
fItemText.Append(")");
}
void
SuperItem::_GetPackageIcon()
float
SuperItem::ZoomWidth(BView *owner)
{
delete fPackageIcon;
fIconSize = int(fPackageItemHeight * .8);
owner->PushState();
owner->SetFont(&fBoldFont);
float width = owner->StringWidth(fItemText.String());
owner->PopState();
return width;
}
BBitmap*
SuperItem::_GetPackageIcon(float listItemHeight)
{
int32 iconSize = int(listItemHeight * .8);
status_t result = B_ERROR;
BRect iconRect(0, 0, fIconSize - 1, fIconSize - 1);
fPackageIcon = new BBitmap(iconRect, 0, B_RGBA32);
BRect iconRect(0, 0, iconSize - 1, iconSize - 1);
BBitmap* packageIcon = new BBitmap(iconRect, 0, B_RGBA32);
BMimeType nodeType;
nodeType.SetTo("application/x-vnd.haiku-package");
result = nodeType.GetIcon(fPackageIcon, icon_size(fIconSize));
result = nodeType.GetIcon(packageIcon, icon_size(iconSize));
// Get super type icon
if (result != B_OK) {
BMimeType superType;
if (nodeType.GetSupertype(&superType) == B_OK)
result = superType.GetIcon(fPackageIcon, icon_size(fIconSize));
result = superType.GetIcon(packageIcon, icon_size(iconSize));
}
if (result != B_OK) {
delete fPackageIcon;
fPackageIcon = NULL;
delete packageIcon;
return NULL;
}
return packageIcon;
}
@@ -767,12 +841,19 @@ PackageItem::PackageItem(const char* name, const char* simple_version,
fDetailedVersion(detailed_version),
fRepository(repository),
fSummary(summary),
fSmallFont(be_plain_font),
fSuperItem(super),
fFileName(file_name),
fDownloadProgress(0),
fDrawBarFlag(false)
fDrawBarFlag(false),
fMoreDetailsWidth(0),
fLessDetailsWidth(0)
{
fLabelOffset = be_control_look->DefaultLabelSpacing();
fSmallFont.SetSize(be_plain_font->Size() - 2);
fSmallFont.GetHeight(&fSmallFontHeight);
fSmallTotalHeight = fSmallFontHeight.ascent + fSmallFontHeight.descent
+ fSmallFontHeight.leading;
}
@@ -786,9 +867,9 @@ PackageItem::DrawItem(BView* owner, BRect item_rect, bool complete)
float offsetWidth = 0;
bool showMoreDetails = fSuperItem->GetDetailLevel();
BBitmap* icon = fSuperItem->GetIcon();
BBitmap* icon = fSuperItem->GetIcon(showMoreDetails);
if (icon != NULL && icon->IsValid()) {
int16 iconSize = fSuperItem->GetIconSize();
float iconSize = icon->Bounds().Height();
float offsetMarginHeight = floor((Height() - iconSize) / 2);
owner->SetDrawingMode(B_OP_ALPHA);
BPoint location = BPoint(item_rect.left,
@@ -801,15 +882,14 @@ PackageItem::DrawItem(BView* owner, BRect item_rect, bool complete)
_DrawBar(location, owner, icon_size(iconSize));
}
owner->SetFont(&fRegularFont);
owner->SetFont(be_plain_font);
owner->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR));
// Package name
font_height fontHeight = fSuperItem->GetFontHeight();
BString name(fName);
owner->TruncateString(&name, B_TRUNCATE_END, nameWidth);
BPoint cursor(item_rect.left + offsetWidth,
item_rect.bottom - fSmallTotalHeight - fontHeight.descent - 1);
item_rect.bottom - fSmallTotalHeight - fSmallFontHeight.descent - 2);
if (showMoreDetails)
cursor.y -= fSmallTotalHeight + 1;
owner->DrawString(name.String(), cursor);
@@ -905,21 +985,49 @@ void
PackageItem::Update(BView *owner, const BFont *font)
{
BListItem::Update(owner, font);
SetItemHeight(font);
SetHeight(fSuperItem->GetPackageItemHeight());
}
void
PackageItem::SetItemHeight(const BFont* font)
PackageItem::CalculateZoomWidths(BView *owner)
{
SetHeight(fSuperItem->GetPackageItemHeight());
owner->PushState();
fRegularFont = *font;
fSmallFont = *font;
fSmallFont.SetSize(font->Size() - 2);
fSmallFont.GetHeight(&fSmallFontHeight);
fSmallTotalHeight = fSmallFontHeight.ascent + fSmallFontHeight.descent
+ fSmallFontHeight.leading;
// More details
float offsetWidth = 2 * be_control_look->DefaultItemSpacing()
+ be_plain_font->Size()
+ fSuperItem->GetIconSize(true) + fLabelOffset;
// Name and repo
owner->SetFont(be_plain_font);
float stringWidth = owner->StringWidth(fName.String());
owner->SetFont(&fSmallFont);
stringWidth += fLabelOffset + owner->StringWidth(fRepository.String());
// Summary
float summaryWidth = owner->StringWidth(fSummary.String());
if (summaryWidth > stringWidth)
stringWidth = summaryWidth;
// Version
float versionWidth = owner->StringWidth(fDetailedVersion.String());
if (versionWidth > stringWidth)
stringWidth = versionWidth;
fMoreDetailsWidth = offsetWidth + stringWidth;
// Less details
offsetWidth = 2 * be_control_look->DefaultItemSpacing()
+ be_plain_font->Size()
+ fSuperItem->GetIconSize(false) + fLabelOffset;
// Name and version
owner->SetFont(be_plain_font);
stringWidth = owner->StringWidth(fName.String());
owner->SetFont(&fSmallFont);
stringWidth += fLabelOffset + owner->StringWidth(fSimpleVersion.String());
// Summary
if (summaryWidth > stringWidth)
stringWidth = summaryWidth;
fLessDetailsWidth = offsetWidth + stringWidth;
owner->PopState();
}
@@ -966,16 +1074,18 @@ void
PackageListView::FrameResized(float newWidth, float newHeight)
{
BOutlineListView::FrameResized(newWidth, newHeight);
float count = CountItems();
for (int32 i = 0; i < count; i++) {
BListItem *item = ItemAt(i);
item->Update(this, be_plain_font);
}
Invalidate();
}
void
PackageListView::ExpandOrCollapse(BListItem *superItem, bool expand)
{
BOutlineListView::ExpandOrCollapse(superItem, expand);
Window()->PostMessage(kMsgSetZoomLimits);
}
void
PackageListView::AddPackage(uint32 install_type, const char* name,
const char* cur_ver, const char* new_ver, const char* summary,
@@ -1049,6 +1159,7 @@ PackageListView::AddPackage(uint32 install_type, const char* name,
super);
AddUnder(item, super);
super->SetItemCount(CountItemsUnder(super, true));
item->CalculateZoomWidths(this);
}
@@ -1119,6 +1230,33 @@ PackageListView::SetMoreDetails(bool showMore)
}
BPoint
PackageListView::ZoomPoint()
{
BPoint zoomPoint(0, 0);
int32 count = CountItems();
for (int32 i = 0; i < count; i++)
{
BListItem* item = ItemAt(i);
float itemWidth = 0;
if (item->OutlineLevel() == 0) {
SuperItem* sItem = dynamic_cast<SuperItem*>(item);
itemWidth = sItem->ZoomWidth(this);
} else {
PackageItem* pItem = dynamic_cast<PackageItem*>(item);
itemWidth = fShowMoreDetails ? pItem->MoreDetailsWidth()
: pItem->LessDetailsWidth();
}
if (itemWidth > zoomPoint.x)
zoomPoint.x = itemWidth;
}
if (count > 0)
zoomPoint.y = ItemFrame(count - 1).bottom;
return zoomPoint;
}
void
PackageListView::_SetItemHeights()
{
@@ -39,29 +39,27 @@ public:
SuperItem(const char* label);
~SuperItem();
virtual void DrawItem(BView*, BRect, bool);
virtual void Update(BView *owner, const BFont *font);
font_height GetFontHeight() { return fFontHeight; };
float GetPackageItemHeight()
{ return fPackageItemHeight; };
BBitmap* GetIcon() { return fPackageIcon; };
int16 GetIconSize() { return fIconSize; };
float GetPackageItemHeight();
float GetPackageItemHeight(bool showMoreDetails);
BBitmap* GetIcon(bool showMoreDetails);
float GetIconSize(bool showMoreDetails);
void SetDetailLevel(bool showMoreDetails);
bool GetDetailLevel() { return fShowMoreDetails; };
void SetItemCount(int32 count)
{ fItemCount = count; };
void SetItemCount(int32 count);
float ZoomWidth(BView *owner);
private:
void _SetHeights();
void _GetPackageIcon();
BBitmap* _GetPackageIcon(float listItemHeight);
BString fLabel;
BString fItemText;
BFont fRegularFont;
BFont fBoldFont;
bool fShowMoreDetails;
font_height fFontHeight;
float fPackageItemHeight;
BBitmap* fPackageIcon;
int16 fIconSize;
font_height fBoldFontHeight;
float fPackageItemLineHeight;
BBitmap* fPackageLessIcon;
BBitmap* fPackageMoreIcon;
int32 fItemCount;
};
@@ -77,11 +75,15 @@ public:
SuperItem* super);
virtual void DrawItem(BView*, BRect, bool);
virtual void Update(BView *owner, const BFont *font);
void SetItemHeight(const BFont* font);
void CalculateZoomWidths(BView *owner);
int NameCompare(PackageItem* item);
const char* FileName() { return fFileName.String(); };
void SetDownloadProgress(float percent);
void ShowProgressBar() { fDrawBarFlag = true; };
float MoreDetailsWidth()
{ return fMoreDetailsWidth; };
float LessDetailsWidth()
{ return fLessDetailsWidth; };
private:
void _DrawBar(BPoint where, BView* view,
@@ -92,7 +94,6 @@ private:
BString fDetailedVersion;
BString fRepository;
BString fSummary;
BFont fRegularFont;
BFont fSmallFont;
font_height fSmallFontHeight;
float fSmallTotalHeight;
@@ -101,6 +102,8 @@ private:
BString fFileName;
float fDownloadProgress;
bool fDrawBarFlag;
float fMoreDetailsWidth;
float fLessDetailsWidth;
};
@@ -108,6 +111,8 @@ class PackageListView : public BOutlineListView {
public:
PackageListView();
virtual void FrameResized(float newWidth, float newHeight);
void ExpandOrCollapse(BListItem *superItem,
bool expand);
void AddPackage(uint32 install_type,
const char* name,
const char* cur_ver,
@@ -120,6 +125,7 @@ public:
void SortItems();
float ItemHeight();
void SetMoreDetails(bool showMore);
BPoint ZoomPoint();
private:
void _SetItemHeights();
@@ -139,6 +145,7 @@ public:
bool QuitRequested();
void FrameMoved(BPoint newPosition);
void FrameResized(float newWidth, float newHeight);
void Zoom(BPoint origin, float width, float height);
void MessageReceived(BMessage* message);
bool ConfirmUpdates();
void UpdatesApplying(const char* header,
@@ -153,7 +160,6 @@ public:
const char* file_name);
void ShowWarningAlert(const char* text);
BBitmap GetIcon(int32 iconSize);
BBitmap GetNotificationIcon();
BRect GetDefaultRect() { return fDefaultRect; };
BPoint GetLocation() { return Frame().LeftTop(); };
BLayoutItem* layout_item_for(BView* view);
@@ -199,6 +205,8 @@ private:
bool fSaveFrameChanges;
BMessageRunner* fMessageRunner;
BMessage fFrameChangeMessage;
float fZoomHeightBaseline;
float fZoomWidthBaseline;
};
+6 -5
View File
@@ -56,10 +56,14 @@ UpdateManager::UpdateManager(BPackageInstallationLocation location,
UpdateManager::~UpdateManager()
{
if (fStatusWindow != NULL)
if (fStatusWindow != NULL) {
fStatusWindow->Lock();
fStatusWindow->Quit();
if (fProblemWindow != NULL)
}
if (fProblemWindow != NULL) {
fProblemWindow->Lock();
fProblemWindow->Quit();
}
}
@@ -550,9 +554,6 @@ UpdateManager::_FinalUpdate(const char* header, const char* text)
notification.SetGroup("SoftwareUpdater");
notification.SetTitle(header);
notification.SetContent(text);
BBitmap icon(fStatusWindow->GetNotificationIcon());
if (icon.IsValid())
notification.SetIcon(&icon);
notification.Send();
}
+1
View File
@@ -53,6 +53,7 @@ static const uint32 kMsgRegister = 'iREG';
static const uint32 kMsgFinalQuit = 'iFIN';
static const uint32 kMsgMoreDetailsToggle = 'iDTO';
static const uint32 kMsgWindowFrameChanged = 'iWFC';
static const uint32 kMsgSetZoomLimits = 'iSZL';
// Message data keys
#define kKeyHeader "key_header"