• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
13const CGFloat kCornerRadius = 2;
14
15const CGFloat kTopBottomTextPadding = 7;
16const CGFloat kLeftRightTextPadding = 15;
17const SkColor kTextShadowColor = SkColorSetRGB(0x53, 0x8c, 0xea);
18
19const SkColor kShadowColor = SkColorSetRGB(0xe9, 0xe9, 0xe9);
20const SkColor kDefaultColor = SkColorSetRGB(0x5a, 0x97, 0xff);
21const SkColor kHoverColor = SkColorSetRGB(0x55, 0x8f, 0xf3);
22const SkColor kPressedColor = SkColorSetRGB(0x42, 0x79, 0xd8);
23
24const SkColor kInnerRingColor = SkColorSetRGB(0x64, 0x9e, 0xff);
25const SkColor kFocusInnerRingColor = SkColorSetRGB(0xad, 0xcc, 0xff);
26const SkColor kPressInnerRingColor = SkColorSetRGB(0x3f, 0x73, 0xcd);
27
28const SkColor kOuterRingColor = SkColorSetRGB(0x2b, 0x67, 0xce);
29const 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