Home | History | Annotate | Download | only in bookmarks
      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