summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-13 23:22:33 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-13 23:22:33 +0000
commit0735266658f996210b6f43142ce7f4c55f47ae13 (patch)
treed4e2c01970b8c7df5f6428f2aac188515a4ea509 /chrome/browser
parent9993401b31ffd1b18f100982f8d75824019f9a11 (diff)
downloadchromium_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.h12
-rw-r--r--chrome/browser/cocoa/background_gradient_view.mm79
-rw-r--r--chrome/browser/cocoa/background_gradient_view_unittest.mm2
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller.mm2
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.mm2
-rw-r--r--chrome/browser/cocoa/browser_window_controller.h9
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm186
-rw-r--r--chrome/browser/cocoa/browser_window_controller_unittest.mm9
-rw-r--r--chrome/browser/cocoa/find_bar_view.h4
-rw-r--r--chrome/browser/cocoa/find_bar_view.mm25
-rw-r--r--chrome/browser/cocoa/gradient_button_cell.mm161
-rw-r--r--chrome/browser/cocoa/location_bar_cell.mm49
-rw-r--r--chrome/browser/cocoa/tab_cell.mm97
-rw-r--r--chrome/browser/cocoa/tab_controller.mm3
-rw-r--r--chrome/browser/cocoa/tab_view.h5
-rw-r--r--chrome/browser/cocoa/tab_view.mm128
-rw-r--r--chrome/browser/cocoa/toolbar_controller.mm20
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];
}