1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/cocoa/background_gradient_view.h"
7 #import "chrome/browser/themes/theme_properties.h"
8 #import "chrome/browser/themes/theme_service.h"
9 #import "chrome/browser/ui/cocoa/nsview_additions.h"
10 #import "chrome/browser/ui/cocoa/themed_window.h"
11 #include "grit/theme_resources.h"
13 @interface BackgroundGradientView (Private)
15 - (NSColor*)backgroundImageColor;
18 @implementation BackgroundGradientView
20 @synthesize showsDivider = showsDivider_;
22 - (id)initWithFrame:(NSRect)frameRect {
23 if ((self = [super initWithFrame:frameRect])) {
29 - (id)initWithCoder:(NSCoder*)decoder {
30 if ((self = [super initWithCoder:decoder])) {
37 [[NSNotificationCenter defaultCenter] removeObserver:self];
45 - (void)setShowsDivider:(BOOL)show {
46 if (showsDivider_ == show)
49 [self setNeedsDisplay:YES];
52 - (void)drawBackgroundWithOpaque:(BOOL)opaque {
53 const NSRect bounds = [self bounds];
56 // If the background image is semi transparent then we need something
57 // to blend against. Using 20% black gives us a color similar to Windows.
58 [[NSColor colorWithCalibratedWhite:0.2 alpha:1.0] set];
62 [[self backgroundImageColor] set];
63 NSRectFillUsingOperation(bounds, NSCompositeSourceOver);
67 [[self strokeColor] set];
68 NSRect borderRect, contentRect;
69 NSDivideRect(bounds, &borderRect, &contentRect, [self cr_lineWidth],
71 NSRectFillUsingOperation(borderRect, NSCompositeSourceOver);
75 - (NSColor*)strokeColor {
76 NSWindow* window = [self window];
78 // Some views have a child NSWindow between them and the window that is
79 // active (e.g, OmniboxPopupTopSeparatorView). For these, check the status
80 // of parentWindow instead. Note that this is not tracked correctly (but
81 // the views that do this appear to be removed when the window loses focus
83 if ([window parentWindow])
84 window = [window parentWindow];
85 BOOL isActive = [window isMainWindow];
87 ui::ThemeProvider* themeProvider = [window themeProvider];
89 return [NSColor blackColor];
90 return themeProvider->GetNSColor(
91 isActive ? ThemeProperties::COLOR_TOOLBAR_STROKE :
92 ThemeProperties::COLOR_TOOLBAR_STROKE_INACTIVE);
95 - (NSColor*)backgroundImageColor {
96 ThemeService* themeProvider =
97 static_cast<ThemeService*>([[self window] themeProvider]);
99 return [[self window] backgroundColor];
101 // Themes don't have an inactive image so only look for one if there's no
103 BOOL isActive = [[self window] isMainWindow];
104 if (!isActive && themeProvider->UsingDefaultTheme()) {
105 NSColor* color = themeProvider->GetNSImageColorNamed(
106 IDR_THEME_TOOLBAR_INACTIVE);
111 return themeProvider->GetNSImageColorNamed(IDR_THEME_TOOLBAR);
114 - (void)windowFocusDidChange:(NSNotification*)notification {
115 // Some child views will indirectly use BackgroundGradientView by calling an
116 // ancestor's draw function (e.g, BookmarkButtonView). Call setNeedsDisplay
117 // on all descendants to ensure that these views re-draw.
118 // TODO(ccameron): Enable these views to listen for focus notifications
120 [self cr_recursivelySetNeedsDisplay:YES];
123 - (void)viewWillMoveToWindow:(NSWindow*)window {
125 [[NSNotificationCenter defaultCenter]
127 name:NSWindowDidBecomeKeyNotification
128 object:[self window]];
129 [[NSNotificationCenter defaultCenter]
131 name:NSWindowDidBecomeMainNotification
132 object:[self window]];
135 [[NSNotificationCenter defaultCenter]
137 selector:@selector(windowFocusDidChange:)
138 name:NSWindowDidBecomeMainNotification
140 [[NSNotificationCenter defaultCenter]
142 selector:@selector(windowFocusDidChange:)
143 name:NSWindowDidResignMainNotification
145 // The new window for the view may have a different focus state than the
146 // last window this view was part of. Force a re-draw to ensure that the
147 // view draws the right state.
148 [self windowFocusDidChange:nil];
150 [super viewWillMoveToWindow:window];
153 - (void)setFrameOrigin:(NSPoint)origin {
154 // The background color depends on the view's vertical position. This impacts
155 // any child views that draw using this view's functions.
156 if (NSMinY([self frame]) != origin.y)
157 [self cr_recursivelySetNeedsDisplay:YES];
159 [super setFrameOrigin:origin];