File: generated_credit_card_bubble_cocoa.mm

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (245 lines) | stat: -rw-r--r-- 8,078 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/cocoa/autofill/generated_credit_card_bubble_cocoa.h"

#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/ui/autofill/generated_credit_card_bubble_controller.h"
#include "chrome/browser/ui/autofill/generated_credit_card_bubble_view.h"
#import "chrome/browser/ui/cocoa/base_bubble_controller.h"
#import "chrome/browser/ui/cocoa/info_bubble_view.h"
#import "chrome/browser/ui/cocoa/info_bubble_window.h"
#include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
#include "skia/ext/skia_utils_mac.h"
#import "ui/base/cocoa/controls/hyperlink_text_view.h"
#include "ui/base/cocoa/window_size_constants.h"
#include "ui/native_theme/native_theme.h"

using autofill::GeneratedCreditCardBubbleCocoa;

namespace {

const CGFloat kTitlePadding = 20.0;
const CGFloat kInset = 20.0;

}  // namespace

// The Cocoa side of the bubble controller.
@interface GeneratedCreditCardBubbleControllerCocoa :
    BaseBubbleController<NSTextViewDelegate> {

  // Bridge to C++ side.
  scoped_ptr<GeneratedCreditCardBubbleCocoa> bridge_;
}

- (id)initWithParentWindow:(NSWindow*)parentWindow
                    bridge:(GeneratedCreditCardBubbleCocoa*)bridge;

// Show the bubble at the given |anchor| point. Coordinates are in screen space.
- (void)showAtAnchor:(NSPoint)anchor;

// Return true if the bubble is in the process of hiding.
- (BOOL)isHiding;

// Build the window contents and lay them out.
- (void)performLayoutWithController:
      (autofill::GeneratedCreditCardBubbleController*)controller;

@end


@implementation GeneratedCreditCardBubbleControllerCocoa

- (id)initWithParentWindow:(NSWindow*)parentWindow
                    bridge:(GeneratedCreditCardBubbleCocoa*)bridge {
  DCHECK(bridge);
  base::scoped_nsobject<InfoBubbleWindow> window(
      [[InfoBubbleWindow alloc]
          initWithContentRect:ui::kWindowSizeDeterminedLater
                    styleMask:NSBorderlessWindowMask
                      backing:NSBackingStoreBuffered
                        defer:NO]);
  if ((self = [super initWithWindow:window
                       parentWindow:parentWindow
                         anchoredAt:NSZeroPoint])) {
    [window setCanBecomeKeyWindow:NO];
    bridge_.reset(bridge);

    ui::NativeTheme* nativeTheme = ui::NativeTheme::instance();
    [[self bubble] setAlignment:info_bubble::kAlignArrowToAnchor];
    [[self bubble] setArrowLocation:info_bubble::kTopRight];
    [[self bubble] setBackgroundColor:
        gfx::SkColorToCalibratedNSColor(nativeTheme->GetSystemColor(
            ui::NativeTheme::kColorId_DialogBackground))];
    [self performLayoutWithController:bridge->controller().get()];
  }
  return self;
}

- (void)windowWillClose:(NSNotification*)notification {
  bridge_->OnBubbleClosing();
  [super windowWillClose:notification];
}

// Called when embedded links are clicked.
- (BOOL)textView:(NSTextView*)textView
   clickedOnLink:(id)link
         atIndex:(NSUInteger)charIndex {
  bridge_->OnLinkClicked();
  return YES;
}

- (void)showAtAnchor:(NSPoint)anchorPoint {
  [self setAnchorPoint:anchorPoint];
  [self showWindow:nil];
}

- (BOOL)isHiding {
  InfoBubbleWindow* window =
      base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]);
  return [window isClosing];
}


- (void)performLayoutWithController:
    (autofill::GeneratedCreditCardBubbleController*)controller {
  CGFloat bubbleWidth = autofill::GeneratedCreditCardBubbleView::kContentsWidth;

  // Build the bubble title.
  NSFont* titleFont = [NSFont systemFontOfSize:15.0];
  NSString* title = base::SysUTF16ToNSString(controller->TitleText());
  base::scoped_nsobject<NSTextField> titleView(
    [[NSTextField alloc] initWithFrame:NSZeroRect]);
  [titleView setDrawsBackground:NO];
  [titleView setBezeled:NO];
  [titleView setEditable:NO];
  [titleView setSelectable:NO];
  [titleView setStringValue:title];
  [titleView setFont:titleFont];
  [titleView sizeToFit];

  bubbleWidth = std::max(bubbleWidth, NSWidth([titleView frame]) + 2 * kInset);

  // Build the contents view.
  base::scoped_nsobject<HyperlinkTextView> contentsView(
      [[HyperlinkTextView alloc] initWithFrame:NSZeroRect]);

  [contentsView setEditable:NO];
  [contentsView setDelegate:self];

  NSFont* font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
  NSFont* boldFont = [NSFont boldSystemFontOfSize:[NSFont systemFontSize]];
  [contentsView setMessage:base::SysUTF16ToNSString(controller->ContentsText())
                  withFont:font
              messageColor:[NSColor blackColor]];

  const std::vector<autofill::TextRange>& text_ranges =
      controller->ContentsTextRanges();
  for (size_t i = 0; i < text_ranges.size(); ++i) {
    NSRange range = text_ranges[i].range.ToNSRange();
    if (text_ranges[i].is_link) {
      [contentsView addLinkRange:range
                        withName:@(i)
                       linkColor:[NSColor blueColor]];
    } else {
       [[contentsView textStorage]
           addAttributes:@{ NSFontAttributeName : boldFont }
                   range:range];
    }
  }

  [contentsView setVerticallyResizable:YES];
  [contentsView setFrameSize:NSMakeSize(bubbleWidth - 2 * kInset, CGFLOAT_MAX)];
  [contentsView sizeToFit];

  // Sizes are computed, now lay out the individual parts.
  [contentsView setFrameOrigin:NSMakePoint(kInset, kInset)];
  [titleView setFrameOrigin:
      NSMakePoint(kInset, NSMaxY([contentsView frame]) + kTitlePadding)];
  [[[self window] contentView] setSubviews:@[ contentsView, titleView ]];

  // Update window frame.
  NSRect windowFrame = [[self window] frame];
  windowFrame.size =
      NSMakeSize(bubbleWidth, NSMaxY([titleView frame]) + kInset);
  [[self window] setFrame:windowFrame display:YES];
}

@end


namespace autofill {

// static
base::WeakPtr<GeneratedCreditCardBubbleView>
    GeneratedCreditCardBubbleView::Create(
        const base::WeakPtr<GeneratedCreditCardBubbleController>& controller) {
  return (new GeneratedCreditCardBubbleCocoa(controller))->weak_ptr_factory_.
      GetWeakPtr();
}

GeneratedCreditCardBubbleCocoa::GeneratedCreditCardBubbleCocoa(
    const base::WeakPtr<GeneratedCreditCardBubbleController>& controller)
    : bubbleController_(nil),
      controller_(controller),
      weak_ptr_factory_(this) {
}

GeneratedCreditCardBubbleCocoa::~GeneratedCreditCardBubbleCocoa() {}

void GeneratedCreditCardBubbleCocoa::Show() {
  DCHECK(controller_.get());
  NSView* browser_view =
      controller_->web_contents()->GetNativeView();
  NSWindow* parent_window = [browser_view window];
  LocationBarViewMac* location_bar =
      [[parent_window windowController] locationBarBridge];

  // |location_bar| can be NULL during initialization stages.
  if (!location_bar) {
    // Technically, Show() should never be called during initialization.
    NOTREACHED();

    delete this;
    return;
  }

  if (!bubbleController_) {
    bubbleController_ = [[GeneratedCreditCardBubbleControllerCocoa alloc]
        initWithParentWindow:parent_window
                      bridge:this];
  }

  // |bubbleController_| is supposed to take ownership of |this|. If it can't be
  // constructed, clean up and abort showing.
  if (!bubbleController_) {
    delete this;
    return;
  }

  NSPoint anchor = location_bar->GetGeneratedCreditCardBubblePoint();
  [bubbleController_ showAtAnchor:[parent_window convertBaseToScreen:anchor]];
}

void GeneratedCreditCardBubbleCocoa::Hide() {
  [bubbleController_ close];
}

bool GeneratedCreditCardBubbleCocoa::IsHiding() const {
  return [bubbleController_ isHiding];
}

void GeneratedCreditCardBubbleCocoa::OnBubbleClosing() {
  bubbleController_ = nil;
}

void GeneratedCreditCardBubbleCocoa::OnLinkClicked() {
  if (controller_)
    controller_->OnLinkClicked();
}

}  // autofill