NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / infobars / infobar_gradient_view.mm
blob1f9a3302094667b110886fa87c9e49b5368b190c
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/infobars/infobar_gradient_view.h"
7 #include "base/mac/scoped_nsobject.h"
8 #include "chrome/browser/infobars/infobar.h"
9 #import "chrome/browser/themes/theme_properties.h"
10 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
11 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
12 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
13 #import "chrome/browser/ui/cocoa/nsview_additions.h"
14 #import "chrome/browser/ui/cocoa/themed_window.h"
15 #include "skia/ext/skia_utils_mac.h"
16 #include "ui/base/theme_provider.h"
18 @implementation InfoBarGradientView
20 @synthesize arrowHeight = arrowHeight_;
21 @synthesize arrowHalfWidth = arrowHalfWidth_;
22 @synthesize arrowX = arrowX_;
23 @synthesize hasTip = hasTip_;
25 - (id)initWithFrame:(NSRect)frame {
26   if ((self = [super initWithFrame:frame])) {
27     hasTip_ = YES;
29     // If layer squashing is not supported, then do not give infobars their own
30     // view, so that they will have sub-pixel anti-aliasing, except when a
31     // superview requests a layer (presentation mode only).
32     if ([self cr_supportsLayerSquashing]) {
33       // Give this view its own layer and squash child layers into this layer
34       // so that the text in the tabs have sub-pixel anti-aliasing.
35       [self cr_setWantsLayer:YES withSquashing:YES];
36     }
37   }
38   return self;
41 - (id)initWithCoder:(NSCoder*)decoder {
42   if ((self = [super initWithCoder:decoder])) {
43     hasTip_ = YES;
44   }
45   return self;
48 - (void)setInfobarType:(InfoBarDelegate::Type)infobarType {
49   SkColor topColor = InfoBar::GetTopColor(infobarType);
50   SkColor bottomColor = InfoBar::GetBottomColor(infobarType);
51   base::scoped_nsobject<NSGradient> gradient([[NSGradient alloc]
52       initWithStartingColor:gfx::SkColorToCalibratedNSColor(topColor)
53                 endingColor:gfx::SkColorToCalibratedNSColor(bottomColor)]);
54   [self setGradient:gradient];
57 - (NSColor*)strokeColor {
58   ui::ThemeProvider* themeProvider = [[self window] themeProvider];
59   if (!themeProvider)
60     return [NSColor blackColor];
62   BOOL active = [[self window] isMainWindow];
63   return themeProvider->GetNSColor(
64       active ? ThemeProperties::COLOR_TOOLBAR_STROKE :
65                ThemeProperties::COLOR_TOOLBAR_STROKE_INACTIVE);
68 - (void)drawRect:(NSRect)rect {
69   NSRect bounds = [self bounds];
70   bounds.size.height = InfoBar::kDefaultBarTargetHeight;
72   CGFloat tipXOffset = arrowX_ - arrowHalfWidth_;
74   // Around the bounds of the infobar, continue drawing the path into which the
75   // gradient will be drawn.
76   NSBezierPath* infoBarPath = [NSBezierPath bezierPath];
77   [infoBarPath moveToPoint:NSMakePoint(NSMinX(bounds), NSMaxY(bounds))];
79   // Draw the tip.
80   if (hasTip_) {
81     [infoBarPath lineToPoint:NSMakePoint(tipXOffset, NSMaxY(bounds))];
82     [infoBarPath relativeLineToPoint:NSMakePoint(arrowHalfWidth_,
83                                                  arrowHeight_)];
84     [infoBarPath relativeLineToPoint:NSMakePoint(arrowHalfWidth_,
85                                                  -arrowHeight_)];
86   }
87   [infoBarPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds))];
89   // Save off the top path of the infobar.
90   base::scoped_nsobject<NSBezierPath> topPath([infoBarPath copy]);
92   [infoBarPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMinY(bounds))];
93   [infoBarPath lineToPoint:NSMakePoint(NSMinX(bounds), NSMinY(bounds))];
94   [infoBarPath closePath];
96   // Draw the gradient.
97   [[self gradient] drawInBezierPath:infoBarPath angle:270];
99   NSColor* strokeColor = [self strokeColor];
100   if (strokeColor) {
101     [strokeColor set];
103     // Stroke the bottom of the infobar.
104     NSRect borderRect, contentRect;
105     NSDivideRect(bounds, &borderRect, &contentRect, 1, NSMinYEdge);
106     NSRectFillUsingOperation(borderRect, NSCompositeSourceOver);
108     // Re-stroke the top because the tip will have no stroke. This will draw
109     // over the divider drawn by the bottom of the tabstrip.
110     [topPath stroke];
111   }
113   // Add an inner stroke.
114   const CGFloat kHighlightTipHeight = arrowHeight_ - 1;
115   NSBezierPath* highlightPath = [NSBezierPath bezierPath];
116   [highlightPath moveToPoint:NSMakePoint(NSMinX(bounds), NSMaxY(bounds) - 1)];
117   if (hasTip_) {
118     [highlightPath relativeLineToPoint:NSMakePoint(tipXOffset + 1, 0)];
119     [highlightPath relativeLineToPoint:NSMakePoint(arrowHalfWidth_ - 1,
120                                                    kHighlightTipHeight)];
121     [highlightPath relativeLineToPoint:NSMakePoint(arrowHalfWidth_ - 1,
122                                                    -kHighlightTipHeight)];
123   }
124   [highlightPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds) - 1)];
126   [[NSColor colorWithDeviceWhite:1.0 alpha:1.0] setStroke];
127   [highlightPath stroke];
130 - (BOOL)mouseDownCanMoveWindow {
131   return NO;
134 // This view is intentionally not opaque because it overlaps with the findbar.
136 - (BOOL)accessibilityIsIgnored {
137   return NO;
140 - (id)accessibilityAttributeValue:(NSString*)attribute {
141   if ([attribute isEqual:NSAccessibilityRoleAttribute])
142     return NSAccessibilityGroupRole;
144   return [super accessibilityAttributeValue:attribute];
147 - (void)setHasTip:(BOOL)hasTip {
148   if (hasTip_ == hasTip)
149     return;
150   hasTip_ = hasTip;
151   [self setNeedsDisplay:YES];
154 @end