1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #import "chrome/browser/ui/cocoa/bubble_view.h" 6 7 #include "chrome/browser/themes/theme_properties.h" 8 #import "chrome/browser/ui/cocoa/themed_window.h" 9 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSBezierPath+RoundRect.h" 10 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSColor+Luminance.h" 11 #include "ui/base/theme_provider.h" 12 13 // The roundedness of the edges of the bubble. This matches the value used on 14 // Lion for window corners. 15 const int kBubbleCornerRadius = 3; 16 const float kWindowEdge = 0.7f; 17 18 @implementation BubbleView 19 20 // Designated initializer. |provider| is the window from which we get the 21 // current theme to draw text and backgrounds. If nil, the current window will 22 // be checked. The caller needs to ensure |provider| can't go away as it will 23 // not be retained. Defaults to all corners being rounded. 24 - (id)initWithFrame:(NSRect)frame themeProvider:(NSWindow*)provider { 25 if ((self = [super initWithFrame:frame])) { 26 cornerFlags_ = kRoundedAllCorners; 27 themeProvider_ = provider; 28 } 29 return self; 30 } 31 32 // Sets the string displayed in the bubble. A copy of the string is made. 33 - (void)setContent:(NSString*)content { 34 if ([content_ isEqualToString:content]) 35 return; 36 content_.reset([content copy]); 37 [self setNeedsDisplay:YES]; 38 } 39 40 // Sets which corners will be rounded. 41 - (void)setCornerFlags:(unsigned long)flags { 42 if (cornerFlags_ == flags) 43 return; 44 cornerFlags_ = flags; 45 [self setNeedsDisplay:YES]; 46 } 47 48 - (void)setThemeProvider:(NSWindow*)provider { 49 if (themeProvider_ == provider) 50 return; 51 themeProvider_ = provider; 52 [self setNeedsDisplay:YES]; 53 } 54 55 - (NSString*)content { 56 return content_.get(); 57 } 58 59 - (unsigned long)cornerFlags { 60 return cornerFlags_; 61 } 62 63 // The font used to display the content string. 64 - (NSFont*)font { 65 return [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; 66 } 67 68 // Draws the themed background and the text. Will draw a gray bg if no theme. 69 - (void)drawRect:(NSRect)rect { 70 float topLeftRadius = 71 cornerFlags_ & kRoundedTopLeftCorner ? kBubbleCornerRadius : 0; 72 float topRightRadius = 73 cornerFlags_ & kRoundedTopRightCorner ? kBubbleCornerRadius : 0; 74 float bottomLeftRadius = 75 cornerFlags_ & kRoundedBottomLeftCorner ? kBubbleCornerRadius : 0; 76 float bottomRightRadius = 77 cornerFlags_ & kRoundedBottomRightCorner ? kBubbleCornerRadius : 0; 78 79 ui::ThemeProvider* themeProvider = 80 themeProvider_ ? [themeProvider_ themeProvider] : 81 [[self window] themeProvider]; 82 83 // Background / Edge 84 85 NSRect bounds = [self bounds]; 86 bounds = NSInsetRect(bounds, 0.5, 0.5); 87 NSBezierPath* border = 88 [NSBezierPath gtm_bezierPathWithRoundRect:bounds 89 topLeftCornerRadius:topLeftRadius 90 topRightCornerRadius:topRightRadius 91 bottomLeftCornerRadius:bottomLeftRadius 92 bottomRightCornerRadius:bottomRightRadius]; 93 94 if (themeProvider) 95 [themeProvider->GetNSColor(ThemeProperties::COLOR_TOOLBAR) set]; 96 [border fill]; 97 98 [[NSColor colorWithDeviceWhite:kWindowEdge alpha:1.0f] set]; 99 [border stroke]; 100 101 // Text 102 NSColor* textColor = [NSColor blackColor]; 103 if (themeProvider) 104 textColor = themeProvider->GetNSColor(ThemeProperties::COLOR_TAB_TEXT); 105 NSFont* textFont = [self font]; 106 base::scoped_nsobject<NSShadow> textShadow([[NSShadow alloc] init]); 107 [textShadow setShadowBlurRadius:0.0f]; 108 [textShadow.get() setShadowColor:[textColor gtm_legibleTextColor]]; 109 [textShadow.get() setShadowOffset:NSMakeSize(0.0f, -1.0f)]; 110 111 NSDictionary* textDict = [NSDictionary dictionaryWithObjectsAndKeys: 112 textColor, NSForegroundColorAttributeName, 113 textFont, NSFontAttributeName, 114 textShadow.get(), NSShadowAttributeName, 115 nil]; 116 [content_ drawAtPoint:NSMakePoint(kBubbleViewTextPositionX, 117 kBubbleViewTextPositionY) 118 withAttributes:textDict]; 119 } 120 121 @end 122