Home | History | Annotate | Download | only in controls
      1 // Copyright 2013 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 "ui/base/cocoa/controls/blue_label_button.h"
      6 
      7 #include "base/mac/foundation_util.h"
      8 #include "skia/ext/skia_utils_mac.h"
      9 #include "third_party/skia/include/core/SkColor.h"
     10 #include "ui/base/resource/resource_bundle.h"
     11 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
     12 
     13 const CGFloat kCornerRadius = 2;
     14 
     15 const CGFloat kTopBottomTextPadding = 7;
     16 const CGFloat kLeftRightTextPadding = 15;
     17 const SkColor kTextShadowColor = SkColorSetRGB(0x53, 0x8c, 0xea);
     18 
     19 const SkColor kShadowColor = SkColorSetRGB(0xe9, 0xe9, 0xe9);
     20 const SkColor kDefaultColor = SkColorSetRGB(0x5a, 0x97, 0xff);
     21 const SkColor kHoverColor = SkColorSetRGB(0x55, 0x8f, 0xf3);
     22 const SkColor kPressedColor = SkColorSetRGB(0x42, 0x79, 0xd8);
     23 
     24 const SkColor kInnerRingColor = SkColorSetRGB(0x64, 0x9e, 0xff);
     25 const SkColor kFocusInnerRingColor = SkColorSetRGB(0xad, 0xcc, 0xff);
     26 const SkColor kPressInnerRingColor = SkColorSetRGB(0x3f, 0x73, 0xcd);
     27 
     28 const SkColor kOuterRingColor = SkColorSetRGB(0x2b, 0x67, 0xce);
     29 const SkColor kPressOuterRingColor = SkColorSetRGB(0x23, 0x52, 0xa2);
     30 
     31 @interface BlueLabelButtonCell : NSButtonCell
     32 
     33 + (NSAttributedString*)generateAttributedString:(NSString*)buttonText;
     34 
     35 @end
     36 
     37 @implementation BlueLabelButton
     38 
     39 + (Class)cellClass {
     40   return [BlueLabelButtonCell class];
     41 }
     42 
     43 - (id)initWithFrame:(NSRect)frameRect {
     44   if ((self = [super initWithFrame:frameRect])) {
     45     [self setBezelStyle:NSSmallSquareBezelStyle];
     46   }
     47   return self;
     48 }
     49 
     50 @end
     51 
     52 @implementation BlueLabelButtonCell
     53 
     54 + (NSAttributedString*)generateAttributedString:(NSString*)buttonText {
     55   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
     56   NSFont* buttonFont = rb.GetFontList(ui::ResourceBundle::SmallFont).
     57       GetPrimaryFont().GetNativeFont();
     58   base::scoped_nsobject<NSMutableParagraphStyle> buttonTextParagraphStyle(
     59       [[NSMutableParagraphStyle alloc] init]);
     60   [buttonTextParagraphStyle setAlignment:NSCenterTextAlignment];
     61 
     62   base::scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
     63   [shadow setShadowOffset:NSMakeSize(0, -1)];
     64   [shadow setShadowBlurRadius:0];
     65   [shadow setShadowColor:gfx::SkColorToSRGBNSColor(kTextShadowColor)];
     66 
     67   NSDictionary* buttonTextAttributes = @{
     68     NSParagraphStyleAttributeName : buttonTextParagraphStyle,
     69     NSFontAttributeName : buttonFont,
     70     NSForegroundColorAttributeName : [NSColor whiteColor],
     71     NSShadowAttributeName : shadow.get()
     72   };
     73   base::scoped_nsobject<NSAttributedString> attributedButtonText(
     74       [[NSAttributedString alloc] initWithString:buttonText
     75                                       attributes:buttonTextAttributes]);
     76   return attributedButtonText.autorelease();
     77 }
     78 
     79 - (NSSize)cellSize {
     80   NSAttributedString* attributedTitle =
     81       [[self class] generateAttributedString:[self title]];
     82   NSSize textSize = [attributedTitle size];
     83 
     84   // Add 1 to maintain identical height w/ previous drawing code.
     85   textSize.height += 2 * kTopBottomTextPadding + 1;
     86   textSize.width += 2 * kLeftRightTextPadding;
     87   return textSize;
     88 }
     89 
     90 - (NSRect)drawTitle:(NSAttributedString*)title
     91           withFrame:(NSRect)frame
     92              inView:(NSView*)controlView {
     93   // Fuzz factor to adjust for the drop shadow. Based on visual inspection.
     94   frame.origin.y -= 1;
     95 
     96   NSAttributedString* attributedTitle =
     97       [[self class] generateAttributedString:[self title]];
     98   gfx::ScopedNSGraphicsContextSaveGState context;
     99   [attributedTitle drawInRect:frame];
    100   return frame;
    101 }
    102 
    103 - (void)drawBezelWithFrame:(NSRect)frame
    104                     inView:(NSView*)controlView {
    105   NSColor* centerColor;
    106   NSColor* innerColor;
    107   NSColor* outerColor;
    108   HoverState hoverState =
    109       [base::mac::ObjCCastStrict<HoverButton>(controlView) hoverState];
    110   // Leave a sliver of height 1 for the button drop shadow.
    111   frame.size.height -= 1;
    112 
    113   if (hoverState == kHoverStateMouseDown && [self isHighlighted]) {
    114     centerColor = gfx::SkColorToSRGBNSColor(kPressedColor);
    115     innerColor = gfx::SkColorToSRGBNSColor(kPressInnerRingColor);
    116     outerColor = gfx::SkColorToSRGBNSColor(kPressOuterRingColor);
    117   } else {
    118     centerColor = hoverState == kHoverStateMouseOver ?
    119         gfx::SkColorToSRGBNSColor(kHoverColor) :
    120         gfx::SkColorToSRGBNSColor(kDefaultColor);
    121     innerColor = [self showsFirstResponder] ?
    122         gfx::SkColorToSRGBNSColor(kFocusInnerRingColor) :
    123         gfx::SkColorToSRGBNSColor(kInnerRingColor);
    124     outerColor = gfx::SkColorToSRGBNSColor(kOuterRingColor);
    125   }
    126   {
    127     gfx::ScopedNSGraphicsContextSaveGState context;
    128     base::scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
    129     [shadow setShadowOffset:NSMakeSize(0, -1)];
    130     [shadow setShadowBlurRadius:1.0];
    131     [shadow setShadowColor:gfx::SkColorToSRGBNSColor(kShadowColor)];
    132     [shadow set];
    133     [outerColor set];
    134 
    135     [[NSBezierPath bezierPathWithRoundedRect:frame
    136                                      xRadius:kCornerRadius
    137                                      yRadius:kCornerRadius] fill];
    138   }
    139 
    140   [innerColor set];
    141   [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 1, 1)
    142                                    xRadius:kCornerRadius
    143                                    yRadius:kCornerRadius] fill];
    144   [centerColor set];
    145   [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 2, 2)
    146                                    xRadius:kCornerRadius
    147                                    yRadius:kCornerRadius] fill];
    148 }
    149 
    150 @end
    151