1// Copyright (c) 2012 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/info_bubble_view.h"
6
7#include "base/logging.h"
8#import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSBezierPath+RoundRect.h"
9
10@implementation InfoBubbleView
11
12@synthesize arrowLocation = arrowLocation_;
13@synthesize alignment = alignment_;
14@synthesize cornerFlags = cornerFlags_;
15
16- (id)initWithFrame:(NSRect)frameRect {
17  if ((self = [super initWithFrame:frameRect])) {
18    arrowLocation_ = info_bubble::kTopLeft;
19    alignment_ = info_bubble::kAlignArrowToAnchor;
20    cornerFlags_ = info_bubble::kRoundedAllCorners;
21    backgroundColor_.reset([[NSColor whiteColor] retain]);
22  }
23  return self;
24}
25
26- (void)drawRect:(NSRect)rect {
27  // Make room for the border to be seen.
28  NSRect bounds = [self bounds];
29  if (arrowLocation_ != info_bubble::kNoArrow) {
30    bounds.size.height -= info_bubble::kBubbleArrowHeight;
31  }
32  rect.size.height -= info_bubble::kBubbleArrowHeight;
33
34  float topRadius = cornerFlags_ & info_bubble::kRoundedTopCorners ?
35      info_bubble::kBubbleCornerRadius : 0;
36  float bottomRadius = cornerFlags_ & info_bubble::kRoundedBottomCorners ?
37      info_bubble::kBubbleCornerRadius : 0;
38
39  NSBezierPath* bezier =
40      [NSBezierPath gtm_bezierPathWithRoundRect:bounds
41                            topLeftCornerRadius:topRadius
42                           topRightCornerRadius:topRadius
43                         bottomLeftCornerRadius:bottomRadius
44                        bottomRightCornerRadius:bottomRadius];
45
46  // Add the bubble arrow.
47  CGFloat dX = 0;
48  switch (arrowLocation_) {
49    case info_bubble::kTopLeft:
50      dX = info_bubble::kBubbleArrowXOffset;
51      break;
52    case info_bubble::kTopRight:
53      dX = NSWidth(bounds) - info_bubble::kBubbleArrowXOffset -
54          info_bubble::kBubbleArrowWidth;
55      break;
56    case info_bubble::kTopCenter:
57      dX = NSMidX(bounds) - info_bubble::kBubbleArrowWidth / 2.0;
58      break;
59    case info_bubble::kNoArrow:
60      break;
61    default:
62      NOTREACHED();
63      break;
64  }
65  NSPoint arrowStart = NSMakePoint(NSMinX(bounds), NSMaxY(bounds));
66  arrowStart.x += dX;
67  [bezier moveToPoint:NSMakePoint(arrowStart.x, arrowStart.y)];
68  if (arrowLocation_ != info_bubble::kNoArrow) {
69    [bezier lineToPoint:NSMakePoint(arrowStart.x +
70                                        info_bubble::kBubbleArrowWidth / 2.0,
71                                    arrowStart.y +
72                                        info_bubble::kBubbleArrowHeight)];
73  }
74  [bezier lineToPoint:NSMakePoint(arrowStart.x + info_bubble::kBubbleArrowWidth,
75                                  arrowStart.y)];
76  [bezier closePath];
77  [backgroundColor_ set];
78  [bezier fill];
79}
80
81- (NSPoint)arrowTip {
82  NSRect bounds = [self bounds];
83  CGFloat tipXOffset =
84      info_bubble::kBubbleArrowXOffset + info_bubble::kBubbleArrowWidth / 2.0;
85  CGFloat xOffset = 0.0;
86  switch(arrowLocation_) {
87    case info_bubble::kTopRight:
88      xOffset = NSMaxX(bounds) - tipXOffset;
89      break;
90    case info_bubble::kTopLeft:
91      xOffset = NSMinX(bounds) + tipXOffset;
92      break;
93    case info_bubble::kTopCenter:
94      xOffset = NSMidX(bounds);
95      break;
96    default:
97      NOTREACHED();
98      break;
99  }
100  NSPoint arrowTip = NSMakePoint(xOffset, NSMaxY(bounds));
101  return arrowTip;
102}
103
104- (NSColor*)backgroundColor {
105  return backgroundColor_;
106}
107
108- (void)setBackgroundColor:(NSColor*)backgroundColor {
109  backgroundColor_.reset([backgroundColor retain]);
110}
111
112@end
113