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. 4 5 #include "chrome/browser/ui/cocoa/background_gradient_view.h" 6 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" 12 13 @interface BackgroundGradientView (Private) 14 - (void)commonInit; 15 - (NSColor*)backgroundImageColor; 16 @end 17 18 @implementation BackgroundGradientView 19 20 @synthesize showsDivider = showsDivider_; 21 22 - (id)initWithFrame:(NSRect)frameRect { 23 if ((self = [super initWithFrame:frameRect])) { 24 [self commonInit]; 25 } 26 return self; 27 } 28 29 - (id)initWithCoder:(NSCoder*)decoder { 30 if ((self = [super initWithCoder:decoder])) { 31 [self commonInit]; 32 } 33 return self; 34 } 35 36 - (void)dealloc { 37 [[NSNotificationCenter defaultCenter] removeObserver:self]; 38 [super dealloc]; 39 } 40 41 - (void)commonInit { 42 showsDivider_ = YES; 43 [[NSNotificationCenter defaultCenter] 44 addObserver:self 45 selector:@selector(windowFocusDidChange:) 46 name:NSApplicationWillBecomeActiveNotification 47 object:NSApp]; 48 [[NSNotificationCenter defaultCenter] 49 addObserver:self 50 selector:@selector(windowFocusDidChange:) 51 name:NSApplicationWillResignActiveNotification 52 object:NSApp]; 53 } 54 55 - (void)setShowsDivider:(BOOL)show { 56 if (showsDivider_ == show) 57 return; 58 showsDivider_ = show; 59 [self setNeedsDisplay:YES]; 60 } 61 62 - (void)drawBackgroundWithOpaque:(BOOL)opaque { 63 const NSRect bounds = [self bounds]; 64 65 if (opaque) { 66 // If the background image is semi transparent then we need something 67 // to blend against. Using 20% black gives us a color similar to Windows. 68 [[NSColor colorWithCalibratedWhite:0.2 alpha:1.0] set]; 69 NSRectFill(bounds); 70 } 71 72 [[self backgroundImageColor] set]; 73 NSRectFillUsingOperation(bounds, NSCompositeSourceOver); 74 75 if (showsDivider_) { 76 // Draw bottom stroke 77 [[self strokeColor] set]; 78 NSRect borderRect, contentRect; 79 NSDivideRect(bounds, &borderRect, &contentRect, [self cr_lineWidth], 80 NSMinYEdge); 81 NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); 82 } 83 } 84 85 - (NSColor*)strokeColor { 86 NSWindow* window = [self window]; 87 if ([window parentWindow]) 88 window = [window parentWindow]; 89 90 BOOL isActive = [window isMainWindow]; 91 ui::ThemeProvider* themeProvider = [window themeProvider]; 92 if (!themeProvider) 93 return [NSColor blackColor]; 94 return themeProvider->GetNSColor( 95 isActive ? ThemeProperties::COLOR_TOOLBAR_STROKE : 96 ThemeProperties::COLOR_TOOLBAR_STROKE_INACTIVE); 97 } 98 99 - (NSColor*)backgroundImageColor { 100 ThemeService* themeProvider = 101 static_cast<ThemeService*>([[self window] themeProvider]); 102 if (!themeProvider) 103 return [[self window] backgroundColor]; 104 105 // Themes don't have an inactive image so only look for one if there's no 106 // theme. 107 if (![[self window] isMainWindow] && themeProvider->UsingDefaultTheme()) { 108 NSColor* color = themeProvider->GetNSImageColorNamed( 109 IDR_THEME_TOOLBAR_INACTIVE); 110 if (color) 111 return color; 112 } 113 114 return themeProvider->GetNSImageColorNamed(IDR_THEME_TOOLBAR); 115 } 116 117 - (void)windowFocusDidChange:(NSNotification*)notification { 118 // The background color depends on the window's focus state. 119 [self cr_recursivelySetNeedsDisplay:YES]; 120 } 121 122 - (void)viewWillMoveToWindow:(NSWindow*)window { 123 if ([self window]) { 124 [[NSNotificationCenter defaultCenter] 125 removeObserver:self 126 name:NSWindowDidBecomeKeyNotification 127 object:[self window]]; 128 [[NSNotificationCenter defaultCenter] 129 removeObserver:self 130 name:NSWindowDidBecomeMainNotification 131 object:[self window]]; 132 } 133 if (window) { 134 [[NSNotificationCenter defaultCenter] 135 addObserver:self 136 selector:@selector(windowFocusDidChange:) 137 name:NSWindowDidBecomeKeyNotification 138 object:[self window]]; 139 [[NSNotificationCenter defaultCenter] 140 addObserver:self 141 selector:@selector(windowFocusDidChange:) 142 name:NSWindowDidBecomeMainNotification 143 object:[self window]]; 144 } 145 [super viewWillMoveToWindow:window]; 146 } 147 148 - (void)setFrameOrigin:(NSPoint)origin { 149 // The background color depends on the view's vertical position. 150 if (NSMinY([self frame]) != origin.y) 151 [self setNeedsDisplay:YES]; 152 153 [super setFrameOrigin:origin]; 154 } 155 156 @end 157