Chromium Code Reviews| Index: chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm |
| diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm |
| index 835ba3c004dfc3cca482e2ac7f9f142dc79e1ed1..6b5871d79baf891b76e15cb7cf242040f613598d 100644 |
| --- a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm |
| +++ b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm |
| @@ -92,6 +92,9 @@ const CGFloat kWarningsSeparatorPadding = 14; |
| // The left padding for the link cell. |
| const CGFloat kLinkCellPaddingLeft = 3; |
| +// Size of individual extension icons for bundle installs. |
| +const CGFloat kExtensionIconSize = 32; |
| + |
| // Maximum height we will adjust controls to when trying to accomodate their |
| // contents. |
| const CGFloat kMaxControlHeight = 250; |
| @@ -102,6 +105,12 @@ NSString* const kCellAttributesKey = @"cellAttributes"; |
| NSString* const kPermissionsDetailIndex = @"permissionsDetailIndex"; |
| NSString* const kPermissionsDetailType = @"permissionsDetailType"; |
| +CGFloat ComputeDesiredControlHeight(NSControl* control) { |
|
Alexei Svitkine (slow)
2015/04/21 16:40:52
Add a comment above.
Marc Treib
2015/04/22 08:09:16
Done.
|
| + NSRect rect = [control frame]; |
| + rect.size.height = kMaxControlHeight; |
| + return [[control cell] cellSizeForBounds:rect].height; |
| +} |
| + |
| // Adjust the |control|'s height so that its content is not clipped. |
| // This also adds the change in height to the |totalOffset| and shifts the |
| // control down by that amount. |
| @@ -109,9 +118,7 @@ void OffsetControlVerticallyToFitContent(NSControl* control, |
| CGFloat* totalOffset) { |
| // Adjust the control's height so that its content is not clipped. |
| NSRect currentRect = [control frame]; |
| - NSRect fitRect = currentRect; |
| - fitRect.size.height = kMaxControlHeight; |
| - CGFloat desiredHeight = [[control cell] cellSizeForBounds:fitRect].height; |
| + CGFloat desiredHeight = ComputeDesiredControlHeight(control); |
| CGFloat offset = desiredHeight - NSHeight(currentRect); |
| [control setFrameSize:NSMakeSize(NSWidth(currentRect), |
| @@ -125,6 +132,32 @@ void OffsetControlVerticallyToFitContent(NSControl* control, |
| [control setFrameOrigin:origin]; |
| } |
| +// Adjust the |view|'s height so that its subviews are not clipped. |
| +// This also adds the change in height to the |totalOffset| and shifts the |
| +// control down by that amount. |
| +void OffsetViewVerticallyToFitContent(NSView* view, CGFloat* totalOffset) { |
| + // Adjust the view's height so that its subviews are not clipped. |
| + CGFloat desiredHeight = 0; |
| + for (NSView* subview in [view subviews]) { |
| + int requiredHeight = NSMaxY([subview frame]); |
| + if (requiredHeight > desiredHeight) { |
|
Alexei Svitkine (slow)
2015/04/21 16:40:52
Nit: No {}'s
Marc Treib
2015/04/22 08:09:16
Done.
|
| + desiredHeight = requiredHeight; |
| + } |
| + } |
| + NSRect currentRect = [view frame]; |
| + CGFloat offset = desiredHeight - NSHeight(currentRect); |
| + |
| + [view setFrameSize:NSMakeSize(NSWidth(currentRect), |
| + NSHeight(currentRect) + offset)]; |
| + |
| + *totalOffset += offset; |
| + |
| + // Move the view vertically by the new total offset. |
| + NSPoint origin = [view frame].origin; |
| + origin.y -= *totalOffset; |
| + [view setFrameOrigin:origin]; |
| +} |
| + |
| // Gets the desired height of |outlineView|. Simply using the view's frame |
| // doesn't work if an animation is pending. |
| CGFloat GetDesiredOutlineViewHeight(NSOutlineView* outlineView) { |
| @@ -270,9 +303,7 @@ bool HasAttribute(id item, CellAttributesMask attributeMask) { |
| gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor())]; |
| } |
| - // The bundle install dialog has no icon. |
| - if (![self isBundleInstall]) |
| - [iconView_ setImage:prompt_->icon().ToNSImage()]; |
| + [iconView_ setImage:prompt_->icon().ToNSImage()]; |
| // The dialog is laid out in the NIB exactly how we want it assuming that |
| // each label fits on one line. However, for each label, we want to allow |
| @@ -309,22 +340,53 @@ bool HasAttribute(id item, CellAttributesMask attributeMask) { |
| } |
| if ([self isBundleInstall]) { |
| - // We display the list of extension names as a simple text string, seperated |
| - // by newlines. |
| BundleInstaller::ItemList items = prompt_->bundle()->GetItemsWithState( |
| BundleInstaller::Item::STATE_PENDING); |
| - NSMutableString* joinedItems = [NSMutableString string]; |
| - for (size_t i = 0; i < items.size(); ++i) { |
| - if (i > 0) |
| - [joinedItems appendString:@"\n"]; |
| - [joinedItems appendString:base::SysUTF16ToNSString( |
| - items[i].GetNameForDisplay())]; |
| + const CGFloat titleWidth = |
| + [itemsField_ frame].size.width - kExtensionIconSize; |
| + CGFloat offset = 0; |
| + // Go over the items backwards, since Cocoa coords go from the bottom up. |
| + for (size_t i = items.size(); i > 0; --i) { |
| + const BundleInstaller::Item& item = items[i - 1]; |
| + |
| + NSString* title = base::SysUTF16ToNSString(item.GetNameForDisplay()); |
| + NSRect titleFrame = NSMakeRect(kExtensionIconSize, offset, titleWidth, 0); |
| + base::scoped_nsobject<NSTextField> titleView( |
| + [[NSTextField alloc] initWithFrame:titleFrame]); |
| + [titleView setBordered:NO]; |
| + [titleView setEditable:NO]; |
| + [titleView setStringValue:title]; |
| + |
| + titleFrame.size.height = ComputeDesiredControlHeight(titleView); |
| + |
| + NSRect iconFrame = |
| + NSMakeRect(0, offset, kExtensionIconSize, kExtensionIconSize); |
| + |
| + // Vertically center-align icon and title. |
| + CGFloat align = (iconFrame.size.height - titleFrame.size.height) / 2; |
| + if (align > 0) |
| + titleFrame.origin.y += align; |
| + else |
| + iconFrame.origin.y -= align; |
| + |
| + [titleView setFrame:titleFrame]; |
| + |
| + gfx::ImageSkia skiaImage = gfx::ImageSkia::CreateFrom1xBitmap(item.icon); |
| + NSImage* image = gfx::NSImageFromImageSkiaWithColorSpace( |
| + skiaImage, base::mac::GetSystemColorSpace()); |
| + base::scoped_nsobject<NSImageView> iconView( |
| + [[NSImageView alloc] initWithFrame:iconFrame]); |
| + [iconView setImage:image]; |
| + |
| + [itemsField_ addSubview:iconView]; |
| + [itemsField_ addSubview:titleView]; |
| + |
| + offset = NSMaxY(NSUnionRect(titleFrame, iconFrame)); |
| } |
| - [itemsField_ setStringValue:joinedItems]; |
| - // Adjust the controls to fit the list of extensions. |
| - OffsetControlVerticallyToFitContent(itemsField_, &totalOffset); |
| + // Adjust the view to fit the list of extensions. |
| + OffsetViewVerticallyToFitContent(itemsField_, &totalOffset); |
| } |
| // If there are any warnings, retained devices or retained files, then we |