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