| Index: chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
|
| diff --git a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
|
| index d42ba95a4e611bbf2479c252834b6e32f1ba0f1f..772ec08d917df7d912e09f099bf84199b87802fa 100644
|
| --- a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
|
| +++ b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
|
| @@ -5,6 +5,7 @@
|
| #import "chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.h"
|
|
|
| #include "base/i18n/rtl.h"
|
| +#include "base/mac/mac_util.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/strings/sys_string_conversions.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| @@ -43,11 +44,15 @@
|
| #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
|
| #import "ui/base/cocoa/controls/hyperlink_text_view.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/gfx/image/image_skia_util_mac.h"
|
|
|
| using content::BrowserThread;
|
| using extensions::BundleInstaller;
|
| using extensions::Extension;
|
|
|
| +// Size of individual extension icons for bundle installs.
|
| +const CGFloat kExtensionIconSize = 32;
|
| +
|
| class ExtensionInstalledBubbleBridge
|
| : public ExtensionInstalledBubble::Delegate {
|
| public:
|
| @@ -337,12 +342,12 @@ bool ExtensionInstalledBubbleBridge::MaybeShowNow() {
|
| if (type_ == extension_installed_bubble::kBundle) {
|
| NSInteger installedListHeight =
|
| [self addExtensionList:installedHeadingMsg_
|
| - itemsMsg:installedItemsMsg_
|
| + itemsView:installedItemsView_
|
| state:BundleInstaller::Item::STATE_INSTALLED];
|
|
|
| NSInteger failedListHeight =
|
| [self addExtensionList:failedHeadingMsg_
|
| - itemsMsg:failedItemsMsg_
|
| + itemsView:failedItemsView_
|
| state:BundleInstaller::Item::STATE_FAILED];
|
|
|
| newWindowHeight += installedListHeight + failedListHeight;
|
| @@ -462,41 +467,74 @@ bool ExtensionInstalledBubbleBridge::MaybeShowNow() {
|
| }
|
|
|
| - (NSInteger)addExtensionList:(NSTextField*)headingMsg
|
| - itemsMsg:(NSTextField*)itemsMsg
|
| + itemsView:(NSView*)itemsView
|
| state:(BundleInstaller::Item::State)state {
|
| base::string16 heading = bundle_->GetHeadingTextFor(state);
|
| bool hidden = heading.empty();
|
| [headingMsg setHidden:hidden];
|
| - [itemsMsg setHidden:hidden];
|
| + [itemsView setHidden:hidden];
|
| if (hidden)
|
| return 0;
|
|
|
| [headingMsg setStringValue:base::SysUTF16ToNSString(heading)];
|
| [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:headingMsg];
|
|
|
| - NSMutableString* joinedItems = [NSMutableString string];
|
| + const CGFloat titleWidth = [itemsView frame].size.width - kExtensionIconSize;
|
| + CGFloat offset = 0;
|
| + // Go over the items backwards, since Cocoa coords go from the bottom up.
|
| BundleInstaller::ItemList items = bundle_->GetItemsWithState(state);
|
| - for (size_t i = 0; i < items.size(); ++i) {
|
| - if (i > 0)
|
| - [joinedItems appendString:@"\n"];
|
| - [joinedItems appendString:base::SysUTF16ToNSString(
|
| - items[i].GetNameForDisplay())];
|
| + for (size_t i = items.size(); i > 0; --i) {
|
| + const BundleInstaller::Item& item = items[i - 1];
|
| +
|
| + NSString* title = base::SysUTF16ToNSString(item.GetNameForDisplay());
|
| + base::scoped_nsobject<NSTextField> titleView([[NSTextField alloc]
|
| + initWithFrame:NSMakeRect(kExtensionIconSize, offset, titleWidth, 0)]);
|
| + [titleView setBordered:NO];
|
| + [titleView setEditable:NO];
|
| + [titleView setStringValue:title];
|
| + [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:titleView];
|
| +
|
| + NSRect titleFrame = [titleView frame];
|
| + 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;
|
| + [titleView setFrame:titleFrame];
|
| + } else {
|
| + iconFrame.origin.y -= align;
|
| + }
|
| +
|
| + 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];
|
| +
|
| + [itemsView addSubview:iconView];
|
| + [itemsView addSubview:titleView];
|
| +
|
| + offset = NSMaxY(NSUnionRect(titleFrame, iconFrame));
|
| }
|
|
|
| - [itemsMsg setStringValue:joinedItems];
|
| - [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:itemsMsg];
|
| + NSRect frame = [itemsView frame];
|
| + frame.size.height = offset;
|
| + [itemsView setFrame:frame];
|
|
|
| return NSHeight([headingMsg frame]) +
|
| extension_installed_bubble::kInnerVerticalMargin +
|
| - NSHeight([itemsMsg frame]);
|
| + NSHeight([itemsView frame]);
|
| }
|
|
|
| // Adjust y-position of messages to sit properly in new window height.
|
| - (void)setMessageFrames:(int)newWindowHeight {
|
| if (type_ == extension_installed_bubble::kBundle) {
|
| // Layout the messages from the bottom up.
|
| - NSTextField* msgs[] = { failedItemsMsg_, failedHeadingMsg_,
|
| - installedItemsMsg_, installedHeadingMsg_ };
|
| + NSView* msgs[] = { failedItemsView_, failedHeadingMsg_,
|
| + installedItemsView_, installedHeadingMsg_ };
|
| NSInteger offsetFromBottom = 0;
|
| BOOL isFirstVisible = YES;
|
| for (size_t i = 0; i < arraysize(msgs); ++i) {
|
|
|