 Chromium Code Reviews
 Chromium Code Reviews Issue 12315069:
  Mac: Update zoom bubble UI  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 12315069:
  Mac: Update zoom bubble UI  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| Index: chrome/browser/ui/cocoa/browser/zoom_bubble_controller.mm | 
| diff --git a/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.mm b/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.mm | 
| index 529bd3f51f425945791df3fa32bb88ac7a5ecc3c..3d938d6331204249dcb90f856dfc9ba59fffa32d 100644 | 
| --- a/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.mm | 
| +++ b/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.mm | 
| @@ -4,19 +4,33 @@ | 
| #include "chrome/browser/ui/cocoa/browser/zoom_bubble_controller.h" | 
| +#include "base/mac/foundation_util.h" | 
| #include "base/strings/string_number_conversions.h" | 
| #include "chrome/browser/chrome_page_zoom.h" | 
| +#import "chrome/browser/ui/cocoa/hover_button.h" | 
| #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 
| #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 
| #include "chrome/browser/ui/zoom/zoom_controller.h" | 
| #include "content/public/common/page_zoom.h" | 
| #include "grit/generated_resources.h" | 
| +#include "skia/ext/skia_utils_mac.h" | 
| #import "ui/base/cocoa/window_size_constants.h" | 
| #include "ui/base/l10n/l10n_util.h" | 
| +#include "ui/native_theme/native_theme.h" | 
| @interface ZoomBubbleController (Private) | 
| - (void)performLayout; | 
| - (void)autoCloseBubble; | 
| +- (NSAttributedString*)attributedStringWithString:(NSString*)string | 
| + fontSize:(CGFloat)fontSize; | 
| +- (NSAttributedString*)attributedStringWithStringID:(int)stringID | 
| + fontSize:(CGFloat)fontSize; | 
| +- (void)updateAutoCloseTimer; | 
| +@end | 
| + | 
| +// Button that highlights the background on mouse over. | 
| +@interface ZoomHoverButton : HoverButton { | 
| +} | 
| @end | 
| namespace { | 
| @@ -26,8 +40,23 @@ namespace { | 
| // src/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc. | 
| const NSTimeInterval kAutoCloseDelay = 1.5; | 
| -// The amount of padding between the window frame and controls. | 
| -const CGFloat kPadding = 10.0; | 
| +// The height of the window. | 
| +const CGFloat kWindowHeight = 29.0; | 
| + | 
| +// Width of the zoom in and zoom out buttons. | 
| +const CGFloat kZoomInOutButtonWidth = 44.0; | 
| + | 
| +// Width of zoom label. | 
| +const CGFloat kZoomLabelWidth = 55.0; | 
| + | 
| +// Horizontal margin for the reset zoom button. | 
| +const CGFloat kResetZoomMargin = 9.0; | 
| + | 
| +// The font size text shown in the bubble. | 
| +const CGFloat kTextFontSize = 12.0; | 
| + | 
| +// The font size of the zoom in and zoom out buttons. | 
| +const CGFloat kZoomInOutButtonFontSize = 16.0; | 
| } // namespace | 
| @@ -54,16 +83,16 @@ const CGFloat kPadding = 10.0; | 
| autoClose:(BOOL)autoClose { | 
| contents_ = contents; | 
| [self onZoomChanged]; | 
| + InfoBubbleWindow* window = | 
| + base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]); | 
| + [window setEnableAnimations:autoClose]; | 
| + [window setDelayOnClose:autoClose]; | 
| self.anchorPoint = anchorPoint; | 
| [self showWindow:nil]; | 
| autoClose_ = autoClose; | 
| - if (autoClose_) { | 
| - [self performSelector:@selector(autoCloseBubble) | 
| - withObject:nil | 
| - afterDelay:kAutoCloseDelay]; | 
| - } | 
| + [self updateAutoCloseTimer]; | 
| } | 
| - (void)onZoomChanged { | 
| @@ -72,15 +101,27 @@ const CGFloat kPadding = 10.0; | 
| ZoomController* zoomController = ZoomController::FromWebContents(contents_); | 
| int percent = zoomController->zoom_percent(); | 
| - [zoomPercent_ setStringValue: | 
| - l10n_util::GetNSStringF(IDS_TOOLTIP_ZOOM, base::IntToString16(percent))]; | 
| + NSString *string = | 
| + l10n_util::GetNSStringF(IDS_ZOOM_PERCENT, base::IntToString16(percent)); | 
| + [zoomPercent_ setAttributedStringValue: | 
| + [self attributedStringWithString:string | 
| + fontSize:kTextFontSize]]; | 
| + | 
| + [self updateAutoCloseTimer]; | 
| } | 
| - (void)resetToDefault:(id)sender { | 
| - [self close]; | 
| chrome_page_zoom::Zoom(contents_, content::PAGE_ZOOM_RESET); | 
| } | 
| +- (void)zoomIn:(id)sender { | 
| + chrome_page_zoom::Zoom(contents_, content::PAGE_ZOOM_IN); | 
| +} | 
| + | 
| +- (void)zoomOut:(id)sender { | 
| + chrome_page_zoom::Zoom(contents_, content::PAGE_ZOOM_OUT); | 
| +} | 
| + | 
| - (void)windowWillClose:(NSNotification*)notification { | 
| contents_ = NULL; | 
| closeObserver_.get()(self); | 
| @@ -93,39 +134,87 @@ const CGFloat kPadding = 10.0; | 
| // Private ///////////////////////////////////////////////////////////////////// | 
| - (void)performLayout { | 
| 
Robert Sesek
2013/02/26 16:08:24
This method is a bit too long now.
 
sail
2013/02/26 22:04:15
Done.
Refactored the common button creation code t
 | 
| + ui::NativeTheme *nativeTheme = ui::NativeTheme::instance(); | 
| 
Robert Sesek
2013/02/26 16:08:24
nit: asterisk placement
 
sail
2013/02/26 22:04:15
Done.
 | 
| + | 
| + [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge]; | 
| + [[self bubble] setArrowLocation:info_bubble::kNoArrow]; | 
| + [[self bubble] setBackgroundColor: | 
| + gfx::SkColorToCalibratedNSColor(nativeTheme-> GetSystemColor( | 
| 
Robert Sesek
2013/02/26 16:08:24
nit: space after ->
 
sail
2013/02/26 22:04:15
Done.
 | 
| + ui::NativeTheme::kColorId_DialogBackground))]; | 
| + | 
| NSView* parent = [[self window] contentView]; | 
| - // Create the reset zoom button. | 
| + // Zoom out button. | 
| + NSRect rect = NSMakeRect(0, 0, kZoomInOutButtonWidth, kWindowHeight); | 
| + scoped_nsobject<NSButton> zoomOutButton( | 
| + [[ZoomHoverButton alloc] initWithFrame:rect]); | 
| + [zoomOutButton setAttributedTitle: | 
| + [self attributedStringWithStringID:IDS_ZOOM_MINUS2 | 
| + fontSize:kZoomInOutButtonFontSize]]; | 
| + [[zoomOutButton cell] setBordered:NO]; | 
| + [zoomOutButton setTarget:self]; | 
| + [zoomOutButton setAction:@selector(zoomOut:)]; | 
| + [parent addSubview:zoomOutButton]; | 
| + | 
| + // Create the label to display the current zoom amount. | 
| + rect.origin.x += NSWidth(rect); | 
| + rect.size.width = kZoomLabelWidth; | 
| + zoomPercent_.reset([[NSTextField alloc] initWithFrame:rect]); | 
| + [zoomPercent_ setEditable:NO]; | 
| + [zoomPercent_ setBordered:NO]; | 
| + [zoomPercent_ setDrawsBackground:NO]; | 
| + [zoomPercent_ sizeToFit]; | 
| + [parent addSubview:zoomPercent_]; | 
| + // Vertically center the text field. | 
| + [zoomPercent_ sizeToFit]; | 
| + NSRect zoomRect = rect; | 
| + zoomRect.size.height = NSHeight([zoomPercent_ frame]); | 
| + zoomRect.origin.y = roundf((NSHeight(rect) - NSHeight(zoomRect)) / 2.0); | 
| + [zoomPercent_ setFrame:zoomRect]; | 
| + | 
| + // Zoom in button. | 
| + rect.origin.x += NSWidth(rect); | 
| + rect.size.width = kZoomInOutButtonWidth; | 
| + scoped_nsobject<NSButton> zoomInButton( | 
| + [[ZoomHoverButton alloc] initWithFrame:rect]); | 
| + [zoomInButton setAttributedTitle: | 
| + [self attributedStringWithStringID:IDS_ZOOM_PLUS2 | 
| + fontSize:kZoomInOutButtonFontSize]]; | 
| + [[zoomInButton cell] setBordered:NO]; | 
| + [zoomInButton setTarget:self]; | 
| + [zoomInButton setAction:@selector(zoomIn:)]; | 
| + [parent addSubview:zoomInButton]; | 
| + | 
| + // Separator view. | 
| + rect.origin.x += NSWidth(rect); | 
| + rect.size.width = 1; | 
| + scoped_nsobject<NSBox> separatorView([[NSBox alloc] initWithFrame:rect]); | 
| + [separatorView setBoxType:NSBoxCustom]; | 
| + [separatorView setBorderColor: | 
| + gfx::SkColorToCalibratedNSColor(nativeTheme-> GetSystemColor( | 
| 
Robert Sesek
2013/02/26 16:08:24
nit: space after ->
 
sail
2013/02/26 22:04:15
Done.
 | 
| + ui::NativeTheme::kColorId_MenuSeparatorColor))]; | 
| + [parent addSubview:separatorView]; | 
| + | 
| + // Reset zoom button. | 
| scoped_nsobject<NSButton> resetButton( | 
| - [[NSButton alloc] initWithFrame:NSMakeRect(0, kPadding, 0, 0)]); | 
| - [resetButton setTitle:l10n_util::GetNSStringWithFixup(IDS_ZOOM_SET_DEFAULT)]; | 
| - [resetButton setButtonType:NSMomentaryPushInButton]; | 
| - [[resetButton cell] setControlSize:NSSmallControlSize]; | 
| - [resetButton setBezelStyle:NSRoundedBezelStyle]; | 
| + [[ZoomHoverButton alloc] initWithFrame:NSZeroRect]); | 
| + NSAttributedString* resetTitle = | 
| + [self attributedStringWithStringID:IDS_ZOOM_SET_DEFAULT_SHORT | 
| + fontSize:kTextFontSize]; | 
| + [resetButton setAttributedTitle:resetTitle]; | 
| + [[resetButton cell] setBordered:NO]; | 
| [resetButton setTarget:self]; | 
| [resetButton setAction:@selector(resetToDefault:)]; | 
| [resetButton sizeToFit]; | 
| - | 
| - // Center it within the window. | 
| - NSRect buttonFrame = [resetButton frame]; | 
| - buttonFrame.origin.x = NSMidX([parent frame]) - NSMidX(buttonFrame); | 
| - [resetButton setFrame:buttonFrame]; | 
| + rect.origin.x += NSWidth(rect); | 
| + rect.size.width = [resetTitle size].width + kResetZoomMargin * 2.0; | 
| + [resetButton setFrame:rect]; | 
| [parent addSubview:resetButton]; | 
| + // Update window frame. | 
| NSRect windowFrame = [[self window] frame]; | 
| - | 
| - // Create the label to display the current zoom amount. | 
| - zoomPercent_.reset([[NSTextField alloc] initWithFrame: | 
| - NSMakeRect(kPadding, NSMaxY(buttonFrame), | 
| - NSWidth(windowFrame) - 2 * kPadding, 22)]); | 
| - [zoomPercent_ setEditable:NO]; | 
| - [zoomPercent_ setBezeled:NO]; | 
| - [zoomPercent_ setAlignment:NSCenterTextAlignment]; | 
| - [parent addSubview:zoomPercent_]; | 
| - | 
| - // Adjust the height of the window to fit the content. | 
| - windowFrame.size.height = NSMaxY([zoomPercent_ frame]) + kPadding + | 
| - info_bubble::kBubbleArrowHeight; | 
| + windowFrame.size.height = NSHeight(rect); | 
| + windowFrame.size.width = NSMaxX(rect); | 
| [[self window] setFrame:windowFrame display:YES]; | 
| } | 
| @@ -135,4 +224,58 @@ const CGFloat kPadding = 10.0; | 
| [self close]; | 
| } | 
| +- (NSAttributedString*)attributedStringWithString:(NSString*)string | 
| + fontSize:(CGFloat)fontSize { | 
| + scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( | 
| + [[NSMutableParagraphStyle alloc] init]); | 
| + [paragraphStyle setAlignment:NSCenterTextAlignment]; | 
| + NSDictionary* attributes = @{ | 
| + NSFontAttributeName: | 
| + [NSFont systemFontOfSize:fontSize], | 
| + NSForegroundColorAttributeName: | 
| + [NSColor colorWithCalibratedWhite:0.58 alpha:1.0], | 
| + NSParagraphStyleAttributeName: | 
| + paragraphStyle.get() | 
| + }; | 
| + return [[[NSAttributedString alloc] | 
| + initWithString:string | 
| + attributes:attributes] autorelease]; | 
| +} | 
| + | 
| +- (NSAttributedString*)attributedStringWithStringID:(int)stringID | 
| + fontSize:(CGFloat)fontSize { | 
| + NSString* string = l10n_util::GetNSStringWithFixup(stringID); | 
| + return [self attributedStringWithString:string | 
| + fontSize:fontSize]; | 
| +} | 
| + | 
| +- (void)updateAutoCloseTimer { | 
| + [NSObject cancelPreviousPerformRequestsWithTarget:self | 
| + selector:@selector(autoCloseBubble) | 
| + object:nil]; | 
| + if (autoClose_) { | 
| + [self performSelector:@selector(autoCloseBubble) | 
| + withObject:nil | 
| + afterDelay:kAutoCloseDelay]; | 
| + } | 
| +} | 
| + | 
| +@end | 
| + | 
| +@implementation ZoomHoverButton | 
| + | 
| +- (void)drawRect:(NSRect)rect { | 
| + NSRect bounds = [self bounds]; | 
| + if ([self hoverState] != kHoverStateNone) { | 
| + ui::NativeTheme *nativeTheme = ui::NativeTheme::instance(); | 
| + [gfx::SkColorToCalibratedNSColor(nativeTheme-> GetSystemColor( | 
| 
Robert Sesek
2013/02/26 16:08:24
nit: space after ->
 
sail
2013/02/26 22:04:15
Done.
 | 
| + ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor)) set]; | 
| + NSRectFillUsingOperation(bounds, NSCompositeSourceOver); | 
| + } | 
| + | 
| + [[self cell] drawTitle:[self attributedTitle] | 
| + withFrame:bounds | 
| + inView:self]; | 
| +} | 
| + | 
| @end |