| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h" |
| |
| #include "base/mac/scoped_nsobject.h" |
| #include "chrome/browser/infobars/infobar.h" |
| #import "chrome/browser/themes/theme_properties.h" |
| #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" |
| #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" |
| #import "chrome/browser/ui/cocoa/themed_window.h" |
| #include "skia/ext/skia_utils_mac.h" |
| #include "ui/base/theme_provider.h" |
| |
| namespace { |
| |
| const CGFloat kTipWidth = 23; |
| |
| } // namespace |
| |
| @implementation InfoBarGradientView |
| |
| @synthesize tipApex = tipApex_; |
| @synthesize hasTip = hasTip_; |
| |
| - (id)initWithFrame:(NSRect)frame { |
| if ((self = [super initWithFrame:frame])) { |
| hasTip_ = YES; |
| } |
| return self; |
| } |
| |
| - (id)initWithCoder:(NSCoder*)decoder { |
| if ((self = [super initWithCoder:decoder])) { |
| hasTip_ = YES; |
| } |
| return self; |
| } |
| |
| - (void)setInfobarType:(InfoBarDelegate::Type)infobarType { |
| SkColor topColor = GetInfoBarTopColor(infobarType); |
| SkColor bottomColor = GetInfoBarBottomColor(infobarType); |
| base::scoped_nsobject<NSGradient> gradient([[NSGradient alloc] |
| initWithStartingColor:gfx::SkColorToCalibratedNSColor(topColor) |
| endingColor:gfx::SkColorToCalibratedNSColor(bottomColor)]); |
| [self setGradient:gradient]; |
| } |
| |
| - (NSColor*)strokeColor { |
| ui::ThemeProvider* themeProvider = [[self window] themeProvider]; |
| if (!themeProvider) |
| return [NSColor blackColor]; |
| |
| BOOL active = [[self window] isMainWindow]; |
| return themeProvider->GetNSColor( |
| active ? ThemeProperties::COLOR_TOOLBAR_STROKE : |
| ThemeProperties::COLOR_TOOLBAR_STROKE_INACTIVE); |
| } |
| |
| - (void)drawRect:(NSRect)rect { |
| NSRect bounds = [self bounds]; |
| bounds.size.height = infobars::kBaseHeight; |
| |
| const CGFloat kHalfWidth = kTipWidth / 2.0; |
| NSPoint localApex = [self convertPoint:self.tipApex fromView:nil]; |
| CGFloat tipXOffset = localApex.x - kHalfWidth; |
| |
| // Around the bounds of the infobar, continue drawing the path into which the |
| // gradient will be drawn. |
| NSBezierPath* infoBarPath = [NSBezierPath bezierPath]; |
| [infoBarPath moveToPoint:NSMakePoint(NSMinX(bounds), NSMaxY(bounds))]; |
| |
| // Draw the tip. |
| if (hasTip_) { |
| [infoBarPath lineToPoint:NSMakePoint(tipXOffset, NSMaxY(bounds))]; |
| [infoBarPath relativeLineToPoint:NSMakePoint(kHalfWidth, |
| infobars::kTipHeight)]; |
| [infoBarPath relativeLineToPoint:NSMakePoint(kHalfWidth, |
| -infobars::kTipHeight)]; |
| } |
| [infoBarPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds))]; |
| |
| // Save off the top path of the infobar. |
| base::scoped_nsobject<NSBezierPath> topPath([infoBarPath copy]); |
| |
| [infoBarPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMinY(bounds))]; |
| [infoBarPath lineToPoint:NSMakePoint(NSMinX(bounds), NSMinY(bounds))]; |
| [infoBarPath closePath]; |
| |
| // Draw the gradient. |
| [[self gradient] drawInBezierPath:infoBarPath angle:270]; |
| |
| NSColor* strokeColor = [self strokeColor]; |
| if (strokeColor) { |
| [strokeColor set]; |
| |
| // Stroke the bottom of the infobar. |
| NSRect borderRect, contentRect; |
| NSDivideRect(bounds, &borderRect, &contentRect, 1, NSMinYEdge); |
| NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); |
| |
| // Re-stroke the top because the tip will have no stroke. This will draw |
| // over the divider drawn by the bottom of the tabstrip. |
| [topPath stroke]; |
| } |
| |
| // Add an inner stroke. |
| const CGFloat kHighlightTipHeight = infobars::kTipHeight - 1; |
| NSBezierPath* highlightPath = [NSBezierPath bezierPath]; |
| [highlightPath moveToPoint:NSMakePoint(NSMinX(bounds), NSMaxY(bounds) - 1)]; |
| if (hasTip_) { |
| [highlightPath relativeLineToPoint:NSMakePoint(tipXOffset + 1, 0)]; |
| [highlightPath relativeLineToPoint:NSMakePoint(kHalfWidth - 1, |
| kHighlightTipHeight)]; |
| [highlightPath relativeLineToPoint:NSMakePoint(kHalfWidth - 1, |
| -kHighlightTipHeight)]; |
| } |
| [highlightPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds) - 1)]; |
| |
| [[NSColor colorWithDeviceWhite:1.0 alpha:1.0] setStroke]; |
| [highlightPath stroke]; |
| } |
| |
| - (BOOL)mouseDownCanMoveWindow { |
| return NO; |
| } |
| |
| // This view is intentionally not opaque because it overlaps with the findbar. |
| |
| - (BOOL)accessibilityIsIgnored { |
| return NO; |
| } |
| |
| - (id)accessibilityAttributeValue:(NSString*)attribute { |
| if ([attribute isEqual:NSAccessibilityRoleAttribute]) |
| return NSAccessibilityGroupRole; |
| |
| return [super accessibilityAttributeValue:attribute]; |
| } |
| |
| - (void)setHasTip:(BOOL)hasTip { |
| if (hasTip_ == hasTip) |
| return; |
| hasTip_ = hasTip; |
| [self setNeedsDisplay:YES]; |
| } |
| |
| @end |