diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-13 23:22:33 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-13 23:22:33 +0000 |
commit | 0735266658f996210b6f43142ce7f4c55f47ae13 (patch) | |
tree | d4e2c01970b8c7df5f6428f2aac188515a4ea509 /chrome/browser | |
parent | 9993401b31ffd1b18f100982f8d75824019f9a11 (diff) | |
download | chromium_src-0735266658f996210b6f43142ce7f4c55f47ae13.zip chromium_src-0735266658f996210b6f43142ce7f4c55f47ae13.tar.gz chromium_src-0735266658f996210b6f43142ce7f4c55f47ae13.tar.bz2 |
Initial support for theming on Mac OS X.
Patch by alcor.
Original review: http://codereview.chromium.org/149204
BUG=http://crbug.com/14451
TEST=Open a theme, watch it apply.
Review URL: http://codereview.chromium.org/155355
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20560 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/cocoa/background_gradient_view.h | 12 | ||||
-rw-r--r-- | chrome/browser/cocoa/background_gradient_view.mm | 79 | ||||
-rw-r--r-- | chrome/browser/cocoa/background_gradient_view_unittest.mm | 2 | ||||
-rw-r--r-- | chrome/browser/cocoa/bookmark_bar_controller.mm | 2 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_cocoa.mm | 2 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.h | 9 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 186 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller_unittest.mm | 9 | ||||
-rw-r--r-- | chrome/browser/cocoa/find_bar_view.h | 4 | ||||
-rw-r--r-- | chrome/browser/cocoa/find_bar_view.mm | 25 | ||||
-rw-r--r-- | chrome/browser/cocoa/gradient_button_cell.mm | 161 | ||||
-rw-r--r-- | chrome/browser/cocoa/location_bar_cell.mm | 49 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_cell.mm | 97 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_controller.mm | 3 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_view.h | 5 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_view.mm | 128 | ||||
-rw-r--r-- | chrome/browser/cocoa/toolbar_controller.mm | 20 |
17 files changed, 608 insertions, 185 deletions
diff --git a/chrome/browser/cocoa/background_gradient_view.h b/chrome/browser/cocoa/background_gradient_view.h index efff342..9c04b4d 100644 --- a/chrome/browser/cocoa/background_gradient_view.h +++ b/chrome/browser/cocoa/background_gradient_view.h @@ -6,11 +6,21 @@ #define CHROME_BROWSER_COCOA_BACKGROUND_GRADIENT_VIEW_H_ #import <Cocoa/Cocoa.h> +#import "third_party/GTM/AppKit/GTMTheme.h" // A custom view that draws a 'standard' background gradient. // Base class for other Chromium views. -@interface BackgroundGradientView : NSView +@interface BackgroundGradientView : NSView { + @private + BOOL showsDivider_; +} + +// The color used for the bottom stroke. Public so subclasses can use. +- (NSColor *)strokeColor; + +// Controls whether the bar draws a dividing line at the bottom. +@property(assign) BOOL showsDivider; @end #endif // CHROME_BROWSER_COCOA_BACKGROUND_GRADIENT_VIEW_H_ diff --git a/chrome/browser/cocoa/background_gradient_view.mm b/chrome/browser/cocoa/background_gradient_view.mm index b06e6f7..0be2f56 100644 --- a/chrome/browser/cocoa/background_gradient_view.mm +++ b/chrome/browser/cocoa/background_gradient_view.mm @@ -4,26 +4,77 @@ #include "chrome/browser/cocoa/background_gradient_view.h" +#define kToolbarTopOffset 12 +#define kToolbarMaxHeight 128 + @implementation BackgroundGradientView +@synthesize showsDivider = showsDivider_; + +- (id)initWithFrame:(NSRect)frameRect { + self = [super initWithFrame:frameRect]; + if (self != nil) { + showsDivider_ = YES; + } + return self; +} + +- (void)awakeFromNib { + showsDivider_ = YES; +} + +- (void)setShowsDivider:(BOOL)show { + showsDivider_ = show; + [self setNeedsDisplay:YES]; +} -// TODO(jrg): this may be a good spot to add theme changes. -// "Theme changes" may include both GTMTheme and "Chrome Themes". +// The offset of this pattern to make it line up with the top of the window. +- (NSPoint)patternPhase { + NSPoint phase = NSZeroPoint; + phase.y += NSHeight([[self window] frame]) - kToolbarTopOffset; + return phase; +} - (void)drawRect:(NSRect)rect { BOOL isKey = [[self window] isKeyWindow]; - NSColor* start = - [NSColor colorWithCalibratedWhite: isKey ? 0.95 : 0.98 alpha:1.0]; - NSColor* end = [NSColor colorWithCalibratedWhite:0.90 alpha:1.0]; - NSGradient *gradient = - [[[NSGradient alloc] initWithStartingColor:start endingColor:end] - autorelease]; - [gradient drawInRect:[self bounds] angle:270.0]; - NSRect borderRect, contentRect; - NSDivideRect([self bounds], &borderRect, &contentRect, 1, NSMinYEdge); - - [[NSColor colorWithDeviceWhite:0.0 alpha:0.3] set]; - NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); + GTMTheme *theme = [self gtm_theme]; + + NSImage *backgroundImage = [theme backgroundImageForStyle:GTMThemeStyleToolBar + state:GTMThemeStateActiveWindow]; + if (backgroundImage) { + NSPoint phase = [self patternPhase]; + [[NSGraphicsContext currentContext] setPatternPhase:phase]; + + NSColor *color = [NSColor colorWithPatternImage:backgroundImage]; + [color set]; + NSRectFill([self bounds]); + } else { + CGFloat winHeight = NSHeight([[self window] frame]); + NSGradient *gradient = [theme gradientForStyle:GTMThemeStyleToolBar + state:isKey]; + NSPoint startPoint = [self convertPointFromBase: + NSMakePoint(0, winHeight - kToolbarTopOffset)]; + NSPoint endPoint = [self convertPointFromBase: + NSMakePoint(0, winHeight - kToolbarTopOffset - kToolbarMaxHeight)]; + + [gradient drawFromPoint:startPoint + toPoint:endPoint + options:NSGradientDrawsBeforeStartingLocation | + NSGradientDrawsAfterEndingLocation]; + } + + if (showsDivider_) { + // Draw bottom stroke + [[self strokeColor] set]; + NSRect borderRect, contentRect; + NSDivideRect([self bounds], &borderRect, &contentRect, 1, NSMinYEdge); + NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); + } +} + +- (NSColor*)strokeColor { + return [[self gtm_theme] strokeColorForStyle:GTMThemeStyleToolBar + state:[[self window] isKeyWindow]]; } @end diff --git a/chrome/browser/cocoa/background_gradient_view_unittest.mm b/chrome/browser/cocoa/background_gradient_view_unittest.mm index 0a7fa7e..7a215a3 100644 --- a/chrome/browser/cocoa/background_gradient_view_unittest.mm +++ b/chrome/browser/cocoa/background_gradient_view_unittest.mm @@ -34,6 +34,8 @@ TEST_F(BackgroundGradientViewTest, AddRemove) { // Test drawing, mostly to ensure nothing leaks or crashes. TEST_F(BackgroundGradientViewTest, Display) { [view_ display]; + [view_ setShowsDivider:YES]; + [view_ display]; } } // namespace diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm index 09c988f..7550c99 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller.mm +++ b/chrome/browser/cocoa/bookmark_bar_controller.mm @@ -150,7 +150,7 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; // Preference changing (global state) is handled in // BrowserWindowCocoa::ToggleBookmarkBar(). - (void)toggleBookmarkBar { - [self showBookmarkBar:!barShouldBeShown_ immediately:NO]; + [self showBookmarkBar:!barShouldBeShown_ immediately:YES]; } - (void)setBookmarkBarEnabled:(BOOL)enabled { diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index 4a59a1f..c518571 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -252,7 +252,7 @@ void BrowserWindowCocoa::ShowHTMLDialog(HtmlDialogUIDelegate* delegate, } void BrowserWindowCocoa::UserChangedTheme() { - NOTIMPLEMENTED(); + [controller_ userChangedTheme]; } int BrowserWindowCocoa::GetExtraRenderViewHeight() const { diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h index bcd3c44..f837ac6 100644 --- a/chrome/browser/cocoa/browser_window_controller.h +++ b/chrome/browser/cocoa/browser_window_controller.h @@ -16,6 +16,7 @@ #include "base/scoped_ptr.h" #import "chrome/browser/cocoa/tab_window_controller.h" #import "chrome/browser/cocoa/bookmark_bar_controller.h" +#import "third_party/GTM/AppKit/GTMTheme.h" class Browser; class BrowserWindow; @@ -32,7 +33,9 @@ class TabStripModelObserverBridge; @class ToolbarController; @interface BrowserWindowController : - TabWindowController<NSUserInterfaceValidations,BookmarkURLOpener> { + TabWindowController<NSUserInterfaceValidations, + BookmarkURLOpener, + GTMThemeDelegate> { @private // The ordering of these members is important as it determines the order in // which they are destroyed. |browser_| needs to be destroyed last as most of @@ -52,6 +55,7 @@ class TabStripModelObserverBridge; scoped_nsobject<FindBarCocoaController> findBarCocoaController_; scoped_ptr<StatusBubble> statusBubble_; scoped_nsobject<DownloadShelfController> downloadShelfController_; + scoped_nsobject<GTMTheme> theme_; BOOL ownsBrowser_; // Only ever NO when testing BOOL fullscreen_; } @@ -116,6 +120,9 @@ class TabStripModelObserverBridge; // Returns fullscreen state. - (BOOL)isFullscreen; +// The user changed the theme. +- (void)userChangedTheme; + // Executes the command in the context of the current browser. // |command| is an integer value containing one of the constants defined in the // "chrome/app/chrome_dll_resource.h" file. diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index 3ab343b..d2c4b22 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -6,6 +6,7 @@ #include "base/mac_util.h" #include "base/scoped_nsdisable_screen_updates.h" +#import "base/scoped_nsobject.h" #include "base/sys_string_conversions.h" #include "chrome/app/chrome_dll_resource.h" // IDC_* #include "chrome/browser/browser.h" @@ -29,7 +30,10 @@ #import "chrome/browser/cocoa/tab_strip_controller.h" #import "chrome/browser/cocoa/tab_view.h" #import "chrome/browser/cocoa/toolbar_controller.h" +#import "chrome/browser/browser_theme_provider.h" #include "chrome/common/pref_service.h" +#import "chrome/browser/cocoa/background_gradient_view.h" +#import "third_party/GTM/AppKit/GTMTheme.h" namespace { @@ -39,6 +43,11 @@ const int kWindowGradientHeight = 24; } +@interface GTMTheme (BrowserThemeProviderInitialization) ++ (GTMTheme *)themeWithBrowserThemeProvider:(BrowserThemeProvider*)provider + isOffTheRecord:(BOOL)offTheRecord; +@end + @interface NSWindow (NSPrivateApis) // Note: These functions are private, use -[NSObject respondsToSelector:] // before calling them. @@ -77,9 +86,12 @@ const int kWindowGradientHeight = 24; // We need to adjust where sheets come out of the window, as by default they // erupt from the omnibox, which is rather weird. -- (NSRect)window:(NSWindow *)window -willPositionSheet:(NSWindow *)sheet +- (NSRect)window:(NSWindow*)window +willPositionSheet:(NSWindow*)sheet usingRect:(NSRect)defaultSheetRect; + +// Theme up the window. +- (void)applyTheme; @end @@ -96,7 +108,7 @@ willPositionSheet:(NSWindow *)sheet - (id)initWithBrowser:(Browser*)browser takeOwnership:(BOOL)ownIt { // Use initWithWindowNibPath:: instead of initWithWindowNibName: so we // can override it in a unit test. - NSString *nibpath = [mac_util::MainAppBundle() + NSString* nibpath = [mac_util::MainAppBundle() pathForResource:@"BrowserWindow" ofType:@"nib"]; if ((self = [super initWithWindowNibPath:nibpath owner:self])) { @@ -118,6 +130,8 @@ willPositionSheet:(NSWindow *)sheet if ([window_ respondsToSelector:@selector(setBottomCornerRounded:)]) [window_ setBottomCornerRounded:NO]; + [self applyTheme]; + // Register ourselves for frame changed notifications from the // tabContentArea. [[NSNotificationCenter defaultCenter] @@ -166,6 +180,20 @@ willPositionSheet:(NSWindow *)sheet // Create the bridge for the status bubble. statusBubble_.reset(new StatusBubbleMac([self window])); + +#if 0 + // Move all buttons down two pixels for visual balance. + // TODO(alcor): remove this if we can't prevent window resize from breaking. + NSArray* buttons = + [NSArray arrayWithObjects: + [[self window] standardWindowButton:NSWindowCloseButton], + [[self window] standardWindowButton:NSWindowZoomButton], + [[self window] standardWindowButton:NSWindowMiniaturizeButton], + nil]; + for (NSButton* button in buttons) { + [button setFrame:NSOffsetRect([button frame], 0, -2.0)]; + } +#endif } return self; } @@ -194,7 +222,7 @@ willPositionSheet:(NSWindow *)sheet // |-windowShoudlClose:| returns YES). We must be careful to preserve the // semantics of BrowserWindow::Close() and not call the Browser's dtor directly // from this method. -- (void)windowWillClose:(NSNotification *)notification { +- (void)windowWillClose:(NSNotification*)notification { DCHECK(!browser_->tabstrip_model()->count()); // We can't actually use |-autorelease| here because there's an embedded @@ -239,11 +267,22 @@ willPositionSheet:(NSWindow *)sheet } // Called right after our window became the main window. -- (void)windowDidBecomeMain:(NSNotification *)notification { +- (void)windowDidBecomeMain:(NSNotification*)notification { BrowserList::SetLastActive(browser_.get()); [self saveWindowPositionIfNeeded]; + NSColor* color = [theme_ backgroundPatternColorForStyle:GTMThemeStyleWindow + state:YES]; + [[self window] setBackgroundColor:color]; } +- (void)windowDidResignMain:(NSNotification*)notification { + NSColor* color = [theme_ backgroundPatternColorForStyle:GTMThemeStyleWindow + state:NO]; + [[self window] setBackgroundColor:color]; +} + + + // Called when the user clicks the zoom button (or selects it from the Window // menu). Zoom to the appropriate size based on the content. Make sure we // enforce a minimum width to ensure websites with small intrinsic widths @@ -476,7 +515,7 @@ willPositionSheet:(NSWindow *)sheet browser_->tabstrip_model()->DetachTabContentsAt(index); } -- (NSView *)selectedTabView { +- (NSView*)selectedTabView { return [tabStripController_ selectedTabView]; } @@ -579,7 +618,11 @@ willPositionSheet:(NSWindow *)sheet } - (void)toggleBookmarkBar { - [[toolbarController_ bookmarkBarController] toggleBookmarkBar]; + BookmarkBarController* bar = [toolbarController_ bookmarkBarController]; + [bar toggleBookmarkBar]; + + [(BackgroundGradientView*)[toolbarController_ view] + setShowsDivider:![bar isBookmarkBarVisible]]; } - (BOOL)isDownloadShelfVisible { @@ -727,6 +770,14 @@ willPositionSheet:(NSWindow *)sheet windowShim_->UpdateTitleBar(); } +- (void)userChangedTheme { + [self applyTheme]; +} + +- (GTMTheme *)gtm_themeForWindow:(NSWindow*)window { + return theme_ ? theme_ : [GTMTheme defaultTheme]; +} + @end @implementation BrowserWindowController (Private) @@ -774,7 +825,7 @@ willPositionSheet:(NSWindow *)sheet [self positionOrRemoveToolbar:NO]; } -// If the browser is in incognito mode, install the image view to decordate +// If the browser is in incognito mode, install the image view to decorate // the window at the upper right. Use the same base y coordinate as the // tab strip. - (void)installIncognitoBadge { @@ -782,7 +833,7 @@ willPositionSheet:(NSWindow *)sheet return; static const float kOffset = 4; - NSString *incognitoPath = [mac_util::MainAppBundle() + NSString* incognitoPath = [mac_util::MainAppBundle() pathForResource:@"otr_icon" ofType:@"pdf"]; scoped_nsobject<NSImage> incognitoImage( @@ -795,7 +846,14 @@ willPositionSheet:(NSWindow *)sheet incognitoFrame.size = imageSize; scoped_nsobject<NSImageView> incognitoView( [[NSImageView alloc] initWithFrame:incognitoFrame]); - [incognitoView setImage:incognitoImage]; + [incognitoView setImage:incognitoImage.get()]; + [incognitoView setWantsLayer:YES]; + [incognitoView setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin]; + scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]); + [shadow setShadowColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.5]]; + [shadow setShadowOffset:NSMakeSize(0, -1)]; + [shadow setShadowBlurRadius:2.0]; + [incognitoView setShadow:shadow]; [[[[self window] contentView] superview] addSubview:incognitoView.get()]; } @@ -853,8 +911,8 @@ willPositionSheet:(NSWindow *)sheet windowPreferences->SetBoolean(L"always_on_top", false); } -- (NSRect)window:(NSWindow *)window -willPositionSheet:(NSWindow *)sheet +- (NSRect)window:(NSWindow*)window +willPositionSheet:(NSWindow*)sheet usingRect:(NSRect)defaultSheetRect { NSRect windowFrame = [window frame]; defaultSheetRect.origin.y = windowFrame.size.height - 10; @@ -899,4 +957,108 @@ willPositionSheet:(NSWindow *)sheet return [toolbarController_ customFieldEditorForObject:obj]; } +- (void)applyTheme { + ThemeProvider* theme_provider = browser_->profile()->GetThemeProvider(); + if (theme_provider) { + GTMTheme *theme = [GTMTheme themeWithBrowserThemeProvider: + (BrowserThemeProvider *)theme_provider + isOffTheRecord:browser_->profile()->IsOffTheRecord()]; + theme_.reset([theme retain]); + } +} + @end + +@implementation GTMTheme (BrowserThemeProviderInitialization) ++ (GTMTheme *)themeWithBrowserThemeProvider:(BrowserThemeProvider*)provider + isOffTheRecord:(BOOL)isOffTheRecord { + GTMTheme *theme = [[[GTMTheme alloc] init] autorelease]; + if (isOffTheRecord) { + NSColor* incognitoColor = [NSColor colorWithCalibratedRed:83/255.0 + green:108.0/255.0 + blue:140/255.0 + alpha:1.0]; + [theme setBackgroundColor:incognitoColor]; + return theme; + } + + NSImage* frameImage = provider->GetNSImageNamed(IDR_THEME_FRAME); + NSImage* frameInactiveImage = + provider->GetNSImageNamed(IDR_THEME_FRAME_INACTIVE); + + [theme setValue:frameImage + forAttribute:@"backgroundImage" + style:GTMThemeStyleWindow + state:YES]; + + NSColor* tabTextColor = [NSColor blackColor]; + [theme setValue:tabTextColor + forAttribute:@"textColor" + style:GTMThemeStyleToolBar + state:YES]; + + NSColor* tabInactiveTextColor = [NSColor grayColor]; + [theme setValue:tabInactiveTextColor + forAttribute:@"textColor" + style:GTMThemeStyleToolBar + state:NO]; + + NSColor* bookmarkBarTextColor = [NSColor blackColor]; + [theme setValue:bookmarkBarTextColor + forAttribute:@"textColor" + style:GTMThemeStyleBookmarksBarButton + state:YES]; + + [theme setValue:frameInactiveImage + forAttribute:@"backgroundImage" + style:GTMThemeStyleWindow + state:NO]; + + NSImage* toolbarImage = provider->GetNSImageNamed(IDR_THEME_TOOLBAR); + [theme setValue:toolbarImage + forAttribute:@"backgroundImage" + style:GTMThemeStyleToolBar + state:YES]; + + NSImage* toolbarButtonImage = + provider->GetNSImageNamed(IDR_THEME_BUTTON_BACKGROUND); + if (toolbarButtonImage) { + [theme setValue:toolbarButtonImage + forAttribute:@"backgroundImage" + style:GTMThemeStyleToolBarButton + state:YES]; + } else { + NSColor* startColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.0]; + NSColor* endColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.3]; + scoped_nsobject<NSGradient> gradient([[NSGradient alloc] + initWithStartingColor:startColor + endingColor:endColor]); + + [theme setValue:gradient + forAttribute:@"gradient" + style:GTMThemeStyleToolBarButton + state:YES]; + + [theme setValue:gradient + forAttribute:@"gradient" + style:GTMThemeStyleToolBarButton + state:NO]; + } + + NSColor* toolbarButtonIconColor = + provider->GetNSColorTint(BrowserThemeProvider::TINT_BUTTONS); + [theme setValue:toolbarButtonIconColor + forAttribute:@"iconColor" + style:GTMThemeStyleToolBarButton + state:YES]; + + NSColor* toolbarButtonBorderColor = toolbarButtonIconColor; + [theme setValue:toolbarButtonBorderColor + forAttribute:@"borderColor" + style:GTMThemeStyleToolBar + state:YES]; + + return theme; +} +@end + diff --git a/chrome/browser/cocoa/browser_window_controller_unittest.mm b/chrome/browser/cocoa/browser_window_controller_unittest.mm index c953dc2..be30d9a 100644 --- a/chrome/browser/cocoa/browser_window_controller_unittest.mm +++ b/chrome/browser/cocoa/browser_window_controller_unittest.mm @@ -95,6 +95,15 @@ TEST_F(BrowserWindowControllerTest, TestNormal) { controller_.release(); } +@interface GTMTheme (BrowserThemeProviderInitialization) ++ (GTMTheme *)themeWithBrowserThemeProvider:(BrowserThemeProvider *)provider + isOffTheRecord:(BOOL)isOffTheRecord; +@end + +TEST_F(BrowserWindowControllerTest, TestTheme) { + [controller_ userChangedTheme]; +} + TEST_F(BrowserWindowControllerTest, BookmarkBarControllerIndirection) { EXPECT_FALSE([controller_ isBookmarkBarVisible]); [controller_ toggleBookmarkBar]; diff --git a/chrome/browser/cocoa/find_bar_view.h b/chrome/browser/cocoa/find_bar_view.h index 919f517..0bdf8d5 100644 --- a/chrome/browser/cocoa/find_bar_view.h +++ b/chrome/browser/cocoa/find_bar_view.h @@ -7,9 +7,11 @@ #import <Cocoa/Cocoa.h> +#include "chrome/browser/cocoa/background_gradient_view.h" + // A view that handles painting the border for the FindBar. -@interface FindBarView : NSView { +@interface FindBarView : BackgroundGradientView { } @end diff --git a/chrome/browser/cocoa/find_bar_view.mm b/chrome/browser/cocoa/find_bar_view.mm index 3cbee2d..8c73f4e 100644 --- a/chrome/browser/cocoa/find_bar_view.mm +++ b/chrome/browser/cocoa/find_bar_view.mm @@ -7,29 +7,34 @@ @implementation FindBarView - (void)drawRect:(NSRect)rect { + CGFloat curveSize = 8; // TODO(rohitrao): Make this prettier. - rect = [self bounds]; + rect = NSInsetRect([self bounds], 0.5, 0.5); + rect = NSOffsetRect(rect, 0, 1.0); + NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect)); NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect)); // Inset the bottom points by 1 so we draw the border entirely // inside the frame. - NSPoint bottomLeft = NSMakePoint(NSMinX(rect) + 15, NSMinY(rect) + 1); - NSPoint bottomRight = NSMakePoint(NSMaxX(rect) - 15, NSMinY(rect) + 1); + NSPoint bottomLeft = NSMakePoint(NSMinX(rect) + curveSize, NSMinY(rect) + 1); + NSPoint bottomRight = NSMakePoint(NSMaxX(rect) - curveSize, NSMinY(rect) + 1); NSBezierPath *path = [NSBezierPath bezierPath]; [path moveToPoint:topLeft]; [path curveToPoint:bottomLeft - controlPoint1:NSMakePoint(topLeft.x + 15, topLeft.y) - controlPoint2:NSMakePoint(bottomLeft.x - 15, bottomLeft.y)]; + controlPoint1:NSMakePoint(topLeft.x + curveSize, topLeft.y) + controlPoint2:NSMakePoint(bottomLeft.x - curveSize, bottomLeft.y)]; [path lineToPoint:bottomRight]; [path curveToPoint:topRight - controlPoint1:NSMakePoint(bottomRight.x + 15, bottomRight.y) - controlPoint2:NSMakePoint(topRight.x - 15, topRight.y)]; + controlPoint1:NSMakePoint(bottomRight.x + curveSize, bottomRight.y) + controlPoint2:NSMakePoint(topRight.x - curveSize, topRight.y)]; - [[NSColor colorWithCalibratedWhite:0.90 alpha:1.0] set]; - [path fill]; + [NSGraphicsContext saveGraphicsState]; + [path addClip]; + [super drawRect:rect]; + [NSGraphicsContext restoreGraphicsState]; - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.3] set]; + [[self strokeColor] set]; [path stroke]; } diff --git a/chrome/browser/cocoa/gradient_button_cell.mm b/chrome/browser/cocoa/gradient_button_cell.mm index f8f6173..1ad72d4 100644 --- a/chrome/browser/cocoa/gradient_button_cell.mm +++ b/chrome/browser/cocoa/gradient_button_cell.mm @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "chrome/browser/cocoa/gradient_button_cell.h" +#import "third_party/GTM/AppKit/GTMTheme.h" +#import "base/scoped_nsobject.h" @implementation GradientButtonCell @@ -11,75 +13,162 @@ NSBackgroundStyleLowered : NSBackgroundStyleRaised; } -- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { +- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { // Constants from Cole. Will kConstant them once the feedback loop // is complete. NSRect drawFrame = NSInsetRect(cellFrame, 1.5, 1.5); + NSRect innerFrame = NSInsetRect(cellFrame, 2, 2); ButtonType type = [[(NSControl*)controlView cell] tag]; switch (type) { case kRightButtonType: drawFrame.origin.x -= 20; + innerFrame.origin.x -= 2; + // Fallthrough case kLeftButtonType: case kLeftButtonWithShadowType: drawFrame.size.width += 20; + innerFrame.size.width += 2; default: break; } const float radius = 3.5; - BOOL highlighted = [self isHighlighted]; + BOOL pressed = [self isHighlighted]; + NSWindow* window = [controlView window]; + BOOL active = [window isKeyWindow] || [window isMainWindow]; - // TODO(jrg): convert to GTMTheme + GTMTheme *theme = [controlView gtm_theme]; - NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:drawFrame - xRadius:radius - yRadius:radius]; - NSBezierPath *outerPath = + NSBezierPath* innerPath = + [NSBezierPath bezierPathWithRoundedRect:drawFrame + xRadius:radius + yRadius:radius]; + NSBezierPath* outerPath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(drawFrame, -1, -1) xRadius:radius + 1 yRadius:radius + 1]; - NSGradient *gradient = nil; - - if (highlighted) { - NSColor* start = [NSColor colorWithCalibratedHue:0.6 - saturation:1.0 - brightness:0.6 - alpha:1.0]; - NSColor* end = [NSColor colorWithCalibratedHue:0.6 - saturation:1.0 - brightness:0.8 - alpha:1.0]; - gradient = [[[NSGradient alloc] initWithStartingColor:start - endingColor:end] autorelease]; - } else { - NSColor* start = [NSColor colorWithCalibratedWhite:1.0 alpha:1.0]; - NSColor* end = [NSColor colorWithCalibratedWhite:0.90 alpha:1.0]; - gradient = [[[NSGradient alloc] initWithStartingColor:start - endingColor:end] autorelease]; - } // Stroke the borders and appropriate fill gradient. If we're borderless, // the only time we want to draw the inner gradient is if we're highlighted. - [[NSColor colorWithCalibratedWhite:1.0 alpha:0.25] set]; - if ([self isBordered]) { + if ([self isBordered] || pressed) { + [[NSColor colorWithCalibratedWhite:1.0 alpha:0.25] set]; [outerPath stroke]; - [gradient drawInBezierPath:path angle:90.0]; - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.15] set]; - [path stroke]; - } else { - if (highlighted) - [gradient drawInBezierPath:path angle:90.0]; + + NSImage* backgroundImage = + [theme backgroundImageForStyle:GTMThemeStyleToolBarButton state:YES]; + + if (backgroundImage) { + NSColor* patternColor = [NSColor colorWithPatternImage:backgroundImage]; + [patternColor set]; + // Set the phase to match window. + NSRect trueRect = [controlView convertRectToBase:cellFrame]; + [[NSGraphicsContext currentContext] + setPatternPhase:NSMakePoint(NSMinX(trueRect), NSMaxY(trueRect))]; + [innerPath fill]; + } else { + if (pressed) { + NSGradient* gradient = + [theme gradientForStyle:GTMThemeStyleToolBarButtonPressed + state:active]; + [gradient drawInBezierPath:innerPath angle:90.0]; + } + } + + if (!pressed) { + [NSGraphicsContext saveGraphicsState]; + [innerPath addClip]; + + // Draw the inner glow. + [innerPath setLineWidth:2]; + [[NSColor colorWithCalibratedWhite:1.0 alpha:0.9] setStroke]; + [innerPath stroke]; + + [[NSColor colorWithCalibratedWhite:1.0 alpha:0.9] setStroke]; + [[NSColor colorWithCalibratedWhite:1.0 alpha:0.2] setFill]; + + // Draw the top inner highlight. + NSAffineTransform* highlightTransform = [NSAffineTransform transform]; + [highlightTransform translateXBy:1 yBy:1]; + scoped_nsobject<NSBezierPath> highlightPath([innerPath copy]); + [highlightPath transformUsingAffineTransform:highlightTransform]; + + [highlightPath stroke]; + + NSColor* startColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.666]; + NSColor* endColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.333]; + scoped_nsobject<NSBezierPath> gradient([[NSGradient alloc] + initWithColorsAndLocations:startColor, 0.33, endColor, 1.0, nil]); + + [gradient drawInBezierPath:innerPath angle:90.0]; + + [NSGraphicsContext restoreGraphicsState]; + } + + NSColor* stroke = [theme strokeColorForStyle:GTMThemeStyleToolBarButton + state:active]; + [stroke setStroke]; + + [innerPath setLineWidth:1]; + [innerPath stroke]; } + // If this is the left side of a segmented button, draw a slight shadow. if (type == kLeftButtonWithShadowType) { NSRect borderRect, contentRect; NSDivideRect(cellFrame, &borderRect, &contentRect, 1.0, NSMaxXEdge); - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.15] set]; + NSColor* stroke = [theme strokeColorForStyle:GTMThemeStyleToolBarButton + state:active]; + [[stroke colorWithAlphaComponent:0.2] set]; NSRectFillUsingOperation(NSInsetRect(borderRect, 0, 2), NSCompositeSourceOver); + innerFrame.size.width -= 1.0; } + [self drawInteriorWithFrame:innerFrame inView:controlView]; +} + +- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { + GTMTheme* theme = [controlView gtm_theme]; + + BOOL shouldTheme = YES; + if (shouldTheme) { + BOOL isTemplate = [[self image] isTemplate]; - [self drawInteriorWithFrame:NSOffsetRect(cellFrame, 0, 1) inView:controlView]; + [NSGraphicsContext saveGraphicsState]; + + CGContextRef context = + (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]); + + if (isTemplate) { + scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]); + [shadow setShadowColor:[NSColor whiteColor]]; + [shadow setShadowOffset:NSMakeSize(0, -1.0)]; + [shadow setShadowBlurRadius:1.0]; + [shadow set]; + } + + CGContextBeginTransparencyLayer(context, 0); + NSRect imageRect = NSZeroRect; + imageRect.size = [[self image] size]; + [[self image] setFlipped:[controlView isFlipped]]; + [[self image] drawInRect:[self imageRectForBounds:cellFrame] + fromRect:imageRect + operation:NSCompositeSourceOver + fraction:[self isEnabled] ? 1.0 : 0.5]; + if (isTemplate) { + NSColor* color = [theme iconColorForStyle:GTMThemeStyleToolBarButton + state:YES]; + [color set]; + NSRectFillUsingOperation(cellFrame,NSCompositeSourceAtop); + } + + CGContextEndTransparencyLayer(context); + [NSGraphicsContext restoreGraphicsState]; + } else { + // NSCell draws these uncentered for some reason, probably because of the + // of control in the xib + [super drawInteriorWithFrame:NSOffsetRect(cellFrame, 0, 1) + inView:controlView]; + } } @end diff --git a/chrome/browser/cocoa/location_bar_cell.mm b/chrome/browser/cocoa/location_bar_cell.mm index 2f8698da..e033d61 100644 --- a/chrome/browser/cocoa/location_bar_cell.mm +++ b/chrome/browser/cocoa/location_bar_cell.mm @@ -3,23 +3,58 @@ // found in the LICENSE file. #import "chrome/browser/cocoa/location_bar_cell.h" +#import "third_party/GTM/AppKit/GTMTheme.h" -const NSInteger kBaselineOffset = 1; +const NSInteger kBaselineOffset = 2; @implementation LocationBarCell +- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { + [[NSColor colorWithCalibratedWhite:1.0 alpha:0.25] set]; + NSFrameRectWithWidthUsingOperation(cellFrame, 1, NSCompositeSourceOver); + + NSRect frame = NSInsetRect(cellFrame, 0, 1); + [[NSColor whiteColor] setFill]; + NSRect innerFrame = NSInsetRect(frame, 1, 1); + NSRectFill(innerFrame); + + NSRect shadowFrame, restFrame; + NSDivideRect(innerFrame, &shadowFrame, &restFrame, 1, NSMinYEdge); + + BOOL isMainWindow = [[controlView window] isMainWindow]; + GTMTheme *theme = [controlView gtm_theme]; + NSColor* stroke = [theme strokeColorForStyle:GTMThemeStyleToolBarButton + state:isMainWindow]; + [stroke set]; + NSFrameRectWithWidthUsingOperation(frame, 1.0, NSCompositeSourceOver); + + // Draw the location bar shadow. + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.05] setFill]; + NSRectFillUsingOperation(shadowFrame, NSCompositeSourceOver); + + if ([self showsFirstResponder]) { + [[[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5] set]; + NSFrameRectWithWidthUsingOperation(NSInsetRect(frame, 0, 0), 2, + NSCompositeSourceOver); + } + + [self drawInteriorWithFrame:cellFrame + inView:controlView]; + +} + - (void)drawInteriorWithFrame:(NSRect)cellFrame - inView:(NSView *)controlView { + inView:(NSView*)controlView { [super drawInteriorWithFrame:NSInsetRect(cellFrame, 0, kBaselineOffset) inView:controlView]; } // Override these methods so that the field editor shows up in the right place - (void)editWithFrame:(NSRect)cellFrame - inView:(NSView *)controlView - editor:(NSText *)textObj + inView:(NSView*)controlView + editor:(NSText*)textObj delegate:(id)anObject - event:(NSEvent *)theEvent { + event:(NSEvent*)theEvent { [super editWithFrame:NSInsetRect(cellFrame, 0, kBaselineOffset) inView:controlView editor:textObj @@ -30,8 +65,8 @@ const NSInteger kBaselineOffset = 1; // Override these methods so that the field editor shows up in the right place - (void)selectWithFrame:(NSRect)cellFrame - inView:(NSView *)controlView - editor:(NSText *)textObj + inView:(NSView*)controlView + editor:(NSText*)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength { diff --git a/chrome/browser/cocoa/tab_cell.mm b/chrome/browser/cocoa/tab_cell.mm index 23719e8..9f89c14 100644 --- a/chrome/browser/cocoa/tab_cell.mm +++ b/chrome/browser/cocoa/tab_cell.mm @@ -6,10 +6,6 @@ #import "third_party/GTM/AppKit/GTMTheme.h" #import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" -#define INSET_MULTIPLIER 2.0/3.0 -#define CP1_MULTIPLIER 1.0/3.0 -#define CP2_MULTIPLIER 3.0/8.0 - @implementation TabCell - (id)initTextCell:(NSString *)aString { @@ -21,107 +17,22 @@ } - (NSBackgroundStyle)interiorBackgroundStyle { - return [[GTMTheme defaultTheme] - interiorBackgroundStyleForStyle:GTMThemeStyleTabBarSelected - active:YES]; + return [[[self controlView] gtm_theme] + interiorBackgroundStyleForStyle:GTMThemeStyleTabBarSelected + state:GTMThemeStateActiveWindow]; } // Override drawing the button so that it looks like a Chromium tab instead // of just a normal MacOS button. - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { - [[NSGraphicsContext currentContext] saveGraphicsState]; - NSRect rect = cellFrame; - BOOL active = - [[controlView window] isKeyWindow] || [[controlView window] isMainWindow]; - - BOOL selected = [(NSButton *)controlView state]; - - // Inset by 0.5 in order to draw on pixels rather than on borders (which would - // cause blurry pixels). Decrease height by 1 in order to move away from the - // edge for the dark shadow. - rect = NSInsetRect(rect, 0.5, selected ? 0 : -0.5); - rect.size.height -= 1; - rect.origin.y += 1; - - NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect)); - NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect)); - NSPoint topRight = - NSMakePoint(NSMaxX(rect) - INSET_MULTIPLIER * NSHeight(rect), - NSMinY(rect)); - NSPoint topLeft = - NSMakePoint(NSMinX(rect) + INSET_MULTIPLIER * NSHeight(rect), - NSMinY(rect)); - - float baseControlPointOutset = NSHeight(rect) * CP1_MULTIPLIER; - float bottomControlPointInset = NSHeight(rect) * CP2_MULTIPLIER; - - // Outset many of these values by 1 to cause the fill to bleed outside the - // clip area - NSBezierPath *path = [NSBezierPath bezierPath]; - [path moveToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y + 1)]; - [path lineToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y)]; - [path lineToPoint:bottomLeft]; - [path curveToPoint:topLeft - controlPoint1:NSMakePoint(bottomLeft.x + baseControlPointOutset, - bottomLeft.y) - controlPoint2:NSMakePoint(topLeft.x - bottomControlPointInset, - topLeft.y)]; - [path lineToPoint:topRight]; - [path curveToPoint:bottomRight - controlPoint1:NSMakePoint(topRight.x + bottomControlPointInset, - topRight.y) - controlPoint2:NSMakePoint(bottomRight.x - baseControlPointOutset, - bottomRight.y)]; - [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y)]; - [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y + 1)]; - - GTMTheme *theme = [GTMTheme defaultTheme]; - NSGradient *gradient = nil; - - if (selected) { - gradient = [theme gradientForStyle:GTMThemeStyleTabBarSelected - active:active]; - // Stroke with a translucent black - [[NSColor colorWithCalibratedWhite:0.0 alpha:active ? 0.5 : 0.3] set]; - [[NSGraphicsContext currentContext] saveGraphicsState]; - NSShadow *shadow = [[[NSShadow alloc] init] autorelease]; - [shadow setShadowOffset:NSMakeSize(2, -1)]; - [shadow setShadowBlurRadius:2.0]; - [path fill]; - [[NSGraphicsContext currentContext] restoreGraphicsState]; - } else { - gradient = [theme gradientForStyle:GTMThemeStyleTabBarDeselected - active:active]; - // Stroke with a translucent black - [[NSColor colorWithCalibratedWhite:0.0 alpha:active ? 0.3 : 0.1] set]; - } - - [[NSGraphicsContext currentContext] saveGraphicsState]; - [[NSBezierPath bezierPathWithRect:NSOffsetRect(cellFrame, 0, -1)] addClip]; - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set]; - [path setLineWidth:selected ? 2.0 : 1.0]; - [path stroke]; - - [[NSGraphicsContext currentContext] restoreGraphicsState]; - - [gradient drawInBezierPath:path angle:90.0]; - - if (!selected) { - [path addClip]; - NSRect borderRect, contentRect; - NSDivideRect(rect, &borderRect, &contentRect, 1, NSMaxYEdge); - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.4] set]; - NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); - } - [[NSGraphicsContext currentContext] restoreGraphicsState]; // Inset where the text is drawn to keep it away from the sloping edges of the // tab, the close box, and the icon view. These constants are derived // empirically as the cell doesn't know about the surrounding view objects. // TODO(pinkerton/alcor): Fix this somehow? const int kIconXOffset = 28; - const int kCloseBoxXOffset = 16; + const int kCloseBoxXOffset = 18; NSRect frame = NSOffsetRect(cellFrame, kIconXOffset, 0); frame.size.width -= kCloseBoxXOffset + kIconXOffset; [self drawInteriorWithFrame:frame diff --git a/chrome/browser/cocoa/tab_controller.mm b/chrome/browser/cocoa/tab_controller.mm index 897312a..5c47fb5 100644 --- a/chrome/browser/cocoa/tab_controller.mm +++ b/chrome/browser/cocoa/tab_controller.mm @@ -6,6 +6,7 @@ #include "chrome/browser/cocoa/nsimage_cache.h" #import "chrome/browser/cocoa/tab_controller.h" #import "chrome/browser/cocoa/tab_controller_target.h" +#import "chrome/browser/cocoa/tab_view.h" @implementation TabController @@ -36,7 +37,7 @@ // mark ourselves as needing a redraw. - (void)internalSetSelected:(BOOL)selected { selected_ = selected; - [backgroundButton_ setState:selected]; + [(TabView *)[self view] setState:selected]; [[self view] setNeedsDisplay:YES]; } diff --git a/chrome/browser/cocoa/tab_view.h b/chrome/browser/cocoa/tab_view.h index 2124c20..1e8669e 100644 --- a/chrome/browser/cocoa/tab_view.h +++ b/chrome/browser/cocoa/tab_view.h @@ -8,6 +8,7 @@ #import <Cocoa/Cocoa.h> #include "base/scoped_nsobject.h" +#import "chrome/browser/cocoa/background_gradient_view.h" @class TabController, TabWindowController; @@ -15,7 +16,7 @@ // on the tab strip. Relies on an associated TabController to provide a // target/action for selecting the tab. -@interface TabView : NSView { +@interface TabView : BackgroundGradientView { @private IBOutlet TabController* controller_; // TODO(rohitrao): Add this button to a CoreAnimation layer so we can fade it @@ -47,7 +48,9 @@ NSWindow* dragOverlay_; // weak. The overlay being dragged TabWindowController* targetController_; // weak. Controller being targeted + NSCellStateValue state_; } +@property(assign) NSCellStateValue state; @end #endif // CHROME_BROWSER_COCOA_TAB_VIEW_H_ diff --git a/chrome/browser/cocoa/tab_view.mm b/chrome/browser/cocoa/tab_view.mm index 44d43ac..16d8e10 100644 --- a/chrome/browser/cocoa/tab_view.mm +++ b/chrome/browser/cocoa/tab_view.mm @@ -7,11 +7,23 @@ #include "chrome/browser/cocoa/tab_view.h" #include "chrome/browser/cocoa/tab_window_controller.h" + +// Constants for inset and control points for tab shape. +static const CGFloat kInsetMultiplier = 2.0/3.0; +static const CGFloat kControlPoint1Multiplier = 1.0/3.0; +static const CGFloat kControlPoint2Multiplier = 3.0/8.0; + +static const CGFloat kToolbarTopOffset = 12; +static const CGFloat kToolbarMaxHeight = 128; + @implementation TabView +@synthesize state = state_; + - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { + [self setShowsDivider:NO]; // TODO(alcor): register for theming, either here or the cell // [self gtm_registerForThemeNotifications]; } @@ -19,6 +31,7 @@ } - (void)awakeFromNib { + [self setShowsDivider:NO]; // Set up the tracking rect for the close button mouseover. Add it // to the |closeButton_| view, but we'll handle the message ourself. // The mouseover is always enabled, because the close button works @@ -363,6 +376,121 @@ static const double kDragStartDistance = 3.0; } } +- (NSPoint)patternPhase { + NSPoint phase = NSZeroPoint; + phase.x -= [self convertRect:[self bounds] toView:nil].origin.x; + // offset to start pattern in upper left corner + phase.y += NSHeight([self bounds]) - 1; + return phase; +} + +- (void)drawRect:(NSRect)rect { + [[NSGraphicsContext currentContext] saveGraphicsState]; + rect = [self bounds]; + BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; + BOOL selected = [(NSButton *)self state]; + + // Inset by 0.5 in order to draw on pixels rather than on borders (which would + // cause blurry pixels). Decrease height by 1 in order to move away from the + // edge for the dark shadow. + rect = NSInsetRect(rect, 0.5, -0.5); + rect.origin.y -= 1; + + NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect)); + NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect)); + NSPoint topRight = + NSMakePoint(NSMaxX(rect) - kInsetMultiplier * NSHeight(rect), + NSMaxY(rect)); + NSPoint topLeft = + NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), + NSMaxY(rect)); + + float baseControlPointOutset = NSHeight(rect) * kControlPoint1Multiplier; + float bottomControlPointInset = NSHeight(rect) * kControlPoint2Multiplier; + + // Outset many of these values by 1 to cause the fill to bleed outside the + // clip area. + NSBezierPath *path = [NSBezierPath bezierPath]; + [path moveToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y + 1)]; + [path lineToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y)]; + [path lineToPoint:bottomLeft]; + [path curveToPoint:topLeft + controlPoint1:NSMakePoint(bottomLeft.x + baseControlPointOutset, + bottomLeft.y) + controlPoint2:NSMakePoint(topLeft.x - bottomControlPointInset, + topLeft.y)]; + [path lineToPoint:topRight]; + [path curveToPoint:bottomRight + controlPoint1:NSMakePoint(topRight.x + bottomControlPointInset, + topRight.y) + controlPoint2:NSMakePoint(bottomRight.x - baseControlPointOutset, + bottomRight.y)]; + [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y)]; + [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y + 1)]; + + if (selected) { + // Stroke with a translucent black. + [[NSColor colorWithCalibratedWhite:0.0 alpha:active ? 0.5 : 0.3] set]; + [[NSGraphicsContext currentContext] saveGraphicsState]; + scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]); + [shadow setShadowOffset:NSMakeSize(2, -1)]; + [shadow setShadowBlurRadius:2.0]; + [path fill]; + [[NSGraphicsContext currentContext] restoreGraphicsState]; + } else { + // Stroke with a translucent black. + [[NSBezierPath bezierPathWithRect:NSOffsetRect([self bounds], 0, 1)] + addClip]; + + [[NSColor colorWithCalibratedWhite:0.0 alpha:active ? 0.3 : 0.1] set]; + } + + [[NSGraphicsContext currentContext] saveGraphicsState]; + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set]; + [path setLineWidth:selected ? 2.0 : 1.0]; + [path stroke]; + [[NSGraphicsContext currentContext] restoreGraphicsState]; + + GTMTheme *theme = [[self self] gtm_theme]; + + if (!selected) { + NSColor *windowColor = + [theme backgroundPatternColorForStyle:GTMThemeStyleWindow + state:GTMThemeStateActiveWindow]; + if (windowColor) { + NSPoint phase = [self patternPhase]; + [windowColor set]; + [[NSGraphicsContext currentContext] setPatternPhase:phase]; + } else { + [[NSColor colorWithCalibratedWhite:0.6 alpha:1.0] set]; + } + [path fill]; + } + + // Draw the background. + [[NSGraphicsContext currentContext] saveGraphicsState]; + CGContextRef context = + (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]); + CGContextBeginTransparencyLayer(context, 0); + if (!selected) + CGContextSetAlpha(context, 0.5); + [path addClip]; + [super drawRect:rect]; + + CGContextEndTransparencyLayer(context); + [[NSGraphicsContext currentContext] restoreGraphicsState]; + + // Draw the bottom border. + if (!selected) { + [path addClip]; + NSRect borderRect, contentRect; + NSDivideRect(rect, &borderRect, &contentRect, 1, NSMinYEdge); + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.4] set]; + NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); + } + [[NSGraphicsContext currentContext] restoreGraphicsState]; +} + // Called when the user hits the right mouse button (or control-clicks) to // show a context menu. - (void)rightMouseDown:(NSEvent*)theEvent { diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm index d7cd131..b9b219c 100644 --- a/chrome/browser/cocoa/toolbar_controller.mm +++ b/chrome/browser/cocoa/toolbar_controller.mm @@ -18,7 +18,7 @@ #include "chrome/common/pref_service.h" // Names of images in the bundle for the star icon (normal and 'starred'). -static NSString* const kStarImageName = @"star.pdf"; +static NSString* const kStarImageName = @"star_Template.pdf"; static NSString* const kStarredImageName = @"starred.pdf"; @implementation LocationBarFieldEditor @@ -174,19 +174,27 @@ class PrefObserverBridge : public NotificationObserver { - (void)setStarredState:(BOOL)isStarred { NSString* starImageName = kStarImageName; - if (isStarred) + BOOL isTemplate = YES; + if (isStarred) { starImageName = kStarredImageName; - [starButton_ setImage:nsimage_cache::ImageNamed(starImageName)]; + isTemplate = NO; + } + NSImage* starImage = nsimage_cache::ImageNamed(starImageName); + if (isTemplate) + [starImage setTemplate:YES]; + [starButton_ setImage:starImage]; } - (void)setIsLoading:(BOOL)isLoading { - NSString* imageName = @"go.pdf"; + NSString* imageName = @"go_Template.pdf"; NSInteger tag = IDC_GO; if (isLoading) { - imageName = @"stop.pdf"; + imageName = @"stop_Template.pdf"; tag = IDC_STOP; } - [goButton_ setImage:nsimage_cache::ImageNamed(imageName)]; + NSImage* stopStartImage = nsimage_cache::ImageNamed(imageName); + [stopStartImage setTemplate:YES]; + [goButton_ setImage:stopStartImage]; [goButton_ setTag:tag]; } |