Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / background_gradient_view.mm
blob3ed96d34a1793dc099cdd0dd6258793c8a4b08e9
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/themed_window.h"
10 #include "grit/theme_resources.h"
11 #import "ui/base/cocoa/nsgraphics_context_additions.h"
12 #import "ui/base/cocoa/nsview_additions.h"
14 @interface BackgroundGradientView (Private)
15 - (void)commonInit;
16 - (NSColor*)backgroundImageColor;
17 @end
19 @implementation BackgroundGradientView
21 @synthesize showsDivider = showsDivider_;
23 - (id)initWithFrame:(NSRect)frameRect {
24   if ((self = [super initWithFrame:frameRect])) {
25     [self commonInit];
26   }
27   return self;
30 - (id)initWithCoder:(NSCoder*)decoder {
31   if ((self = [super initWithCoder:decoder])) {
32     [self commonInit];
33   }
34   return self;
37 - (void)commonInit {
38   showsDivider_ = YES;
41 - (void)setShowsDivider:(BOOL)show {
42   if (showsDivider_ == show)
43     return;
44   showsDivider_ = show;
45   [self setNeedsDisplay:YES];
48 - (NSPoint)patternPhase {
49   return [[self window]
50       themeImagePositionForAlignment:THEME_IMAGE_ALIGN_WITH_TAB_STRIP];
53 - (void)drawBackground:(NSRect)dirtyRect {
54   [[NSGraphicsContext currentContext]
55       cr_setPatternPhase:[self patternPhase]
56                  forView:[self cr_viewBeingDrawnTo]];
58   ui::ThemeProvider* themeProvider = [[self window] themeProvider];
59   if (themeProvider && !themeProvider->UsingSystemTheme()) {
60     // If the background image is semi transparent then we need something
61     // to blend against. Using 20% black gives us a color similar to Windows.
62     [[NSColor colorWithCalibratedWhite:0.2 alpha:1.0] set];
63     NSRectFill(dirtyRect);
64   }
66   [[self backgroundImageColor] set];
67   NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
69   if (showsDivider_) {
70     // Draw bottom stroke
71     NSRect borderRect, contentRect;
72     NSDivideRect([self bounds], &borderRect, &contentRect, [self cr_lineWidth],
73                  NSMinYEdge);
74     if (NSIntersectsRect(borderRect, dirtyRect)) {
75       [[self strokeColor] set];
76       NSRectFillUsingOperation(NSIntersectionRect(borderRect, dirtyRect),
77                                NSCompositeSourceOver);
78     }
79   }
82 - (NSColor*)strokeColor {
83   NSWindow* window = [self window];
85   // Some views have a child NSWindow between them and the window that is
86   // active (e.g, OmniboxPopupTopSeparatorView). For these, check the status
87   // of parentWindow instead. Note that this is not tracked correctly (but
88   // the views that do this appear to be removed when the window loses focus
89   // anyway).
90   if ([window parentWindow])
91     window = [window parentWindow];
92   BOOL isActive = [window isMainWindow];
94   ui::ThemeProvider* themeProvider = [window themeProvider];
95   if (!themeProvider)
96     return [NSColor blackColor];
97   return themeProvider->GetNSColor(
98       isActive ? ThemeProperties::COLOR_TOOLBAR_STROKE :
99                  ThemeProperties::COLOR_TOOLBAR_STROKE_INACTIVE);
102 - (NSColor*)backgroundImageColor {
103   ui::ThemeProvider* themeProvider = [[self window] themeProvider];
104   if (!themeProvider)
105     return [[self window] backgroundColor];
107   // Themes don't have an inactive image so only look for one if there's no
108   // theme.
109   BOOL isActive = [[self window] isMainWindow];
110   if (!isActive && themeProvider->UsingSystemTheme()) {
111     NSColor* color = themeProvider->GetNSImageColorNamed(
112         IDR_THEME_TOOLBAR_INACTIVE);
113     if (color)
114       return color;
115   }
117   return themeProvider->GetNSImageColorNamed(IDR_THEME_TOOLBAR);
120 - (void)viewDidMoveToWindow {
121   [super viewDidMoveToWindow];
122   if ([self window]) {
123     // The new window for the view may have a different focus state than the
124     // last window this view was part of.
125     // This happens when the view is moved into a TabWindowOverlayWindow for
126     // tab dragging.
127     [self windowDidChangeActive];
128   }
131 - (void)viewWillStartLiveResize {
132   [super viewWillStartLiveResize];
134   ui::ThemeProvider* themeProvider = [[self window] themeProvider];
135   if (themeProvider && themeProvider->UsingSystemTheme()) {
136     // The default theme's background image is a subtle texture pattern that
137     // we can scale without being easily noticed. Optimize this case by
138     // skipping redraws during live resize.
139     [self setLayerContentsRedrawPolicy:
140         NSViewLayerContentsRedrawOnSetNeedsDisplay];
141   }
144 - (void)viewDidEndLiveResize {
145   [super viewDidEndLiveResize];
147   if ([self layerContentsRedrawPolicy] !=
148       NSViewLayerContentsRedrawDuringViewResize) {
149     // If we have been scaling the layer during live resize, now is the time to
150     // redraw the layer.
151     [self setLayerContentsRedrawPolicy:
152         NSViewLayerContentsRedrawDuringViewResize];
153     [self setNeedsDisplay:YES];
154   }
157 - (void)setFrameOrigin:(NSPoint)origin {
158   // The background color depends on the view's vertical position. This impacts
159   // any child views that draw using this view's functions.
160   // When resizing the window, the view's vertical position (NSMinY) may change
161   // even though our relative position to the nearest window edge is still the
162   // same. Don't redraw unnecessarily in this case.
163   if (![self inLiveResize] && NSMinY([self frame]) != origin.y)
164     [self cr_recursivelySetNeedsDisplay:YES];
166   [super setFrameOrigin:origin];
169 // ThemedWindowDrawing implementation.
171 - (void)windowDidChangeTheme {
172   [self setNeedsDisplay:YES];
175 - (void)windowDidChangeActive {
176   [self setNeedsDisplay:YES];
179 @end