bookmark_bar_toolbar_view.mm revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2011 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#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h"
6
7#include "chrome/browser/search/search.h"
8#include "chrome/browser/themes/theme_properties.h"
9#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h"
10#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
11#import "chrome/browser/ui/cocoa/browser_window_controller.h"
12#import "chrome/browser/ui/cocoa/nsview_additions.h"
13#import "chrome/browser/ui/cocoa/themed_window.h"
14#include "chrome/browser/ui/ntp_background_util.h"
15#include "chrome/browser/ui/search/search_ui.h"
16#include "grit/theme_resources.h"
17#include "skia/ext/skia_utils_mac.h"
18#include "ui/base/theme_provider.h"
19#include "ui/gfx/canvas_skia_paint.h"
20#include "ui/gfx/rect.h"
21#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
22
23const CGFloat kBorderRadius = 3.0;
24
25@interface BookmarkBarToolbarView (Private)
26- (void)drawAsDetachedBubble;
27- (void)drawAsDetachedInstantExtendedUI;
28@end
29
30@implementation BookmarkBarToolbarView
31
32- (BOOL)isOpaque {
33  return [controller_ isInState:BookmarkBar::DETACHED];
34}
35
36- (void)resetCursorRects {
37  NSCursor *arrow = [NSCursor arrowCursor];
38  [self addCursorRect:[self visibleRect] cursor:arrow];
39  [arrow setOnMouseEntered:YES];
40}
41
42- (void)drawRect:(NSRect)rect {
43  if ([controller_ isInState:BookmarkBar::DETACHED] ||
44      [controller_ isAnimatingToState:BookmarkBar::DETACHED] ||
45      [controller_ isAnimatingFromState:BookmarkBar::DETACHED]) {
46    if (chrome::search::IsInstantExtendedAPIEnabled())
47      [self drawAsDetachedInstantExtendedUI];
48    else
49      [self drawAsDetachedBubble];
50  } else {
51    NSPoint phase = [[self window] themePatternPhase];
52    [[NSGraphicsContext currentContext] setPatternPhase:phase];
53    [self drawBackgroundWithOpaque:YES];
54  }
55}
56
57- (void)drawAsDetachedBubble {
58  // The state of our morph; 1 is total bubble, 0 is the regular bar. We use it
59  // to morph the bubble to a regular bar (shape and colour).
60  CGFloat morph = [controller_ detachedMorphProgress];
61
62  NSRect bounds = [self bounds];
63
64  ui::ThemeProvider* themeProvider = [controller_ themeProvider];
65  if (!themeProvider)
66    return;
67
68  gfx::ScopedNSGraphicsContextSaveGState scopedGState;
69
70  // Draw the background.
71  {
72    // CanvasSkiaPaint draws to the NSGraphicsContext during its destructor, so
73    // explicitly scope this.
74    //
75    // Paint the entire bookmark bar, even if the damage rect is much smaller
76    // because PaintBackgroundDetachedMode() assumes that area's origin is
77    // (0, 0) and that its size is the size of the bookmark bar.
78    //
79    // In practice, this sounds worse than it is because redraw time is still
80    // minimal compared to the pause between frames of animations. We were
81    // already repainting the rest of the bookmark bar below without setting a
82    // clip area, anyway. Also, the only time we weren't asked to redraw the
83    // whole bookmark bar is when the find bar is drawn over it.
84    gfx::CanvasSkiaPaint canvas(bounds, true);
85    gfx::Rect area(0, 0, NSWidth(bounds), NSHeight(bounds));
86
87    NtpBackgroundUtil::PaintBackgroundDetachedMode(themeProvider, &canvas,
88        area, [controller_ currentTabContentsHeight]);
89  }
90
91  // Draw our bookmark bar border on top of the background.
92  NSRect frameRect =
93      NSMakeRect(
94          morph * bookmarks::kNTPBookmarkBarPadding,
95          morph * bookmarks::kNTPBookmarkBarPadding,
96          NSWidth(bounds) - 2 * morph * bookmarks::kNTPBookmarkBarPadding,
97          NSHeight(bounds) - 2 * morph * bookmarks::kNTPBookmarkBarPadding);
98  // Now draw a bezier path with rounded rectangles around the area.
99  frameRect = NSInsetRect(frameRect, morph * 0.5, morph * 0.5);
100  NSBezierPath* border =
101      [NSBezierPath bezierPathWithRoundedRect:frameRect
102                                      xRadius:(morph * kBorderRadius)
103                                      yRadius:(morph * kBorderRadius)];
104
105  // Draw the rounded rectangle.
106  NSColor* toolbarColor =
107      themeProvider->GetNSColor(ThemeProperties::COLOR_TOOLBAR, true);
108  CGFloat alpha = morph * [toolbarColor alphaComponent];
109  [[toolbarColor colorWithAlphaComponent:alpha] set];  // Set with opacity.
110  [border fill];
111
112  // Fade in/out the background.
113  {
114    gfx::ScopedNSGraphicsContextSaveGState bgScopedState;
115    [border setClip];
116    NSGraphicsContext* context = [NSGraphicsContext currentContext];
117    CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]);
118    CGContextBeginTransparencyLayer(cgContext, NULL);
119    CGContextSetAlpha(cgContext, 1 - morph);
120    [context setPatternPhase:[[self window] themePatternPhase]];
121    [self drawBackgroundWithOpaque:YES];
122    CGContextEndTransparencyLayer(cgContext);
123  }
124
125  // Draw the border of the rounded rectangle.
126  NSColor* borderColor = themeProvider->GetNSColor(
127      ThemeProperties::COLOR_TOOLBAR_BUTTON_STROKE, true);
128  alpha = morph * [borderColor alphaComponent];
129  [[borderColor colorWithAlphaComponent:alpha] set];  // Set with opacity.
130  [border stroke];
131
132  // Fade in/out the divider.
133  // TODO(viettrungluu): It's not obvious that this divider lines up exactly
134  // with |BackgroundGradientView|'s (in fact, it probably doesn't).
135  NSColor* strokeColor = [self strokeColor];
136  alpha = (1 - morph) * [strokeColor alphaComponent];
137  [[strokeColor colorWithAlphaComponent:alpha] set];
138  NSBezierPath* divider = [NSBezierPath bezierPath];
139  NSPoint dividerStart =
140      NSMakePoint(morph * bookmarks::kNTPBookmarkBarPadding + morph * 0.5,
141                  morph * bookmarks::kNTPBookmarkBarPadding + morph * 0.5);
142  CGFloat dividerWidth =
143      NSWidth(bounds) - 2 * morph * bookmarks::kNTPBookmarkBarPadding - 2 * 0.5;
144  [divider moveToPoint:dividerStart];
145  [divider relativeLineToPoint:NSMakePoint(dividerWidth, 0)];
146  [divider stroke];
147}
148
149- (void)drawAsDetachedInstantExtendedUI {
150  CGFloat morph = [controller_ detachedMorphProgress];
151  NSRect bounds = [self bounds];
152  ui::ThemeProvider* themeProvider = [controller_ themeProvider];
153  if (!themeProvider)
154    return;
155
156  [[NSColor whiteColor] set];
157  NSRectFill([self bounds]);
158
159  // Overlay with a ligher background color.
160  NSColor* toolbarColor = gfx::SkColorToCalibratedNSColor(
161        chrome::search::GetDetachedBookmarkBarBackgroundColor(themeProvider));
162  CGFloat alpha = morph * [toolbarColor alphaComponent];
163  [[toolbarColor colorWithAlphaComponent:alpha] set];
164  NSRectFillUsingOperation(bounds, NSCompositeSourceOver);
165
166  // Fade in/out the background.
167  {
168    gfx::ScopedNSGraphicsContextSaveGState bgScopedState;
169    NSGraphicsContext* context = [NSGraphicsContext currentContext];
170    CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]);
171    CGContextBeginTransparencyLayer(cgContext, NULL);
172    CGContextSetAlpha(cgContext, 1 - morph);
173    [context setPatternPhase:[[self window] themePatternPhase]];
174    [self drawBackgroundWithOpaque:YES];
175    CGContextEndTransparencyLayer(cgContext);
176  }
177
178  // Bottom stroke.
179  NSColor* strokeColor = gfx::SkColorToCalibratedNSColor(
180        chrome::search::GetDetachedBookmarkBarSeparatorColor(themeProvider));
181  strokeColor = [[self strokeColor] blendedColorWithFraction:morph
182                                                     ofColor:strokeColor];
183  strokeColor = [strokeColor colorWithAlphaComponent:0.5];
184  [strokeColor set];
185  NSRect strokeRect = bounds;
186  strokeRect.size.height = [self cr_lineWidth];
187  NSRectFillUsingOperation(strokeRect, NSCompositeSourceOver);
188}
189
190@end  // @implementation BookmarkBarToolbarView
191