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/ntp_background_util.h" 8 #include "chrome/browser/themes/theme_service.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/themed_window.h" 13 #include "ui/base/theme_provider.h" 14 #include "ui/gfx/canvas_skia_paint.h" 15 #include "ui/gfx/rect.h" 16 17 const CGFloat kBorderRadius = 3.0; 18 19 @interface BookmarkBarToolbarView (Private) 20 - (void)drawRectAsBubble:(NSRect)rect; 21 @end 22 23 @implementation BookmarkBarToolbarView 24 25 - (BOOL)isOpaque { 26 return [controller_ isInState:bookmarks::kDetachedState]; 27 } 28 29 - (void)resetCursorRects { 30 NSCursor *arrow = [NSCursor arrowCursor]; 31 [self addCursorRect:[self visibleRect] cursor:arrow]; 32 [arrow setOnMouseEntered:YES]; 33 } 34 35 - (void)drawRect:(NSRect)rect { 36 if ([controller_ isInState:bookmarks::kDetachedState] || 37 [controller_ isAnimatingToState:bookmarks::kDetachedState] || 38 [controller_ isAnimatingFromState:bookmarks::kDetachedState]) { 39 [self drawRectAsBubble:rect]; 40 } else { 41 NSPoint phase = [[self window] themePatternPhase]; 42 [[NSGraphicsContext currentContext] setPatternPhase:phase]; 43 [self drawBackground]; 44 } 45 } 46 47 - (void)drawRectAsBubble:(NSRect)rect { 48 // The state of our morph; 1 is total bubble, 0 is the regular bar. We use it 49 // to morph the bubble to a regular bar (shape and colour). 50 CGFloat morph = [controller_ detachedMorphProgress]; 51 52 NSRect bounds = [self bounds]; 53 54 ui::ThemeProvider* themeProvider = [controller_ themeProvider]; 55 if (!themeProvider) 56 return; 57 58 NSGraphicsContext* context = [NSGraphicsContext currentContext]; 59 [context saveGraphicsState]; 60 61 // Draw the background. 62 { 63 // CanvasSkiaPaint draws to the NSGraphicsContext during its destructor, so 64 // explicitly scope this. 65 // 66 // Paint the entire bookmark bar, even if the damage rect is much smaller 67 // because PaintBackgroundDetachedMode() assumes that area's origin is 68 // (0, 0) and that its size is the size of the bookmark bar. 69 // 70 // In practice, this sounds worse than it is because redraw time is still 71 // minimal compared to the pause between frames of animations. We were 72 // already repainting the rest of the bookmark bar below without setting a 73 // clip area, anyway. Also, the only time we weren't asked to redraw the 74 // whole bookmark bar is when the find bar is drawn over it. 75 gfx::CanvasSkiaPaint canvas(bounds, true); 76 gfx::Rect area(0, 0, NSWidth(bounds), NSHeight(bounds)); 77 78 NtpBackgroundUtil::PaintBackgroundDetachedMode(themeProvider, &canvas, 79 area, [controller_ currentTabContentsHeight]); 80 } 81 82 // Draw our bookmark bar border on top of the background. 83 NSRect frameRect = 84 NSMakeRect( 85 morph * bookmarks::kNTPBookmarkBarPadding, 86 morph * bookmarks::kNTPBookmarkBarPadding, 87 NSWidth(bounds) - 2 * morph * bookmarks::kNTPBookmarkBarPadding, 88 NSHeight(bounds) - 2 * morph * bookmarks::kNTPBookmarkBarPadding); 89 // Now draw a bezier path with rounded rectangles around the area. 90 frameRect = NSInsetRect(frameRect, morph * 0.5, morph * 0.5); 91 NSBezierPath* border = 92 [NSBezierPath bezierPathWithRoundedRect:frameRect 93 xRadius:(morph * kBorderRadius) 94 yRadius:(morph * kBorderRadius)]; 95 96 // Draw the rounded rectangle. 97 NSColor* toolbarColor = 98 themeProvider->GetNSColor(ThemeService::COLOR_TOOLBAR, true); 99 CGFloat alpha = morph * [toolbarColor alphaComponent]; 100 [[toolbarColor colorWithAlphaComponent:alpha] set]; // Set with opacity. 101 [border fill]; 102 103 // Fade in/out the background. 104 [context saveGraphicsState]; 105 [border setClip]; 106 CGContextRef cgContext = (CGContextRef)[context graphicsPort]; 107 CGContextBeginTransparencyLayer(cgContext, NULL); 108 CGContextSetAlpha(cgContext, 1 - morph); 109 [context setPatternPhase:[[self window] themePatternPhase]]; 110 [self drawBackground]; 111 CGContextEndTransparencyLayer(cgContext); 112 [context restoreGraphicsState]; 113 114 // Draw the border of the rounded rectangle. 115 NSColor* borderColor = themeProvider->GetNSColor( 116 ThemeService::COLOR_TOOLBAR_BUTTON_STROKE, true); 117 alpha = morph * [borderColor alphaComponent]; 118 [[borderColor colorWithAlphaComponent:alpha] set]; // Set with opacity. 119 [border stroke]; 120 121 // Fade in/out the divider. 122 // TODO(viettrungluu): It's not obvious that this divider lines up exactly 123 // with |BackgroundGradientView|'s (in fact, it probably doesn't). 124 NSColor* strokeColor = [self strokeColor]; 125 alpha = (1 - morph) * [strokeColor alphaComponent]; 126 [[strokeColor colorWithAlphaComponent:alpha] set]; 127 NSBezierPath* divider = [NSBezierPath bezierPath]; 128 NSPoint dividerStart = 129 NSMakePoint(morph * bookmarks::kNTPBookmarkBarPadding + morph * 0.5, 130 morph * bookmarks::kNTPBookmarkBarPadding + morph * 0.5); 131 CGFloat dividerWidth = 132 NSWidth(bounds) - 2 * morph * bookmarks::kNTPBookmarkBarPadding - 2 * 0.5; 133 [divider moveToPoint:dividerStart]; 134 [divider relativeLineToPoint:NSMakePoint(dividerWidth, 0)]; 135 [divider stroke]; 136 137 // Restore the graphics context. 138 [context restoreGraphicsState]; 139 } 140 141 @end // @implementation BookmarkBarToolbarView 142