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.
5 #include "chrome/browser/ui/views/autofill/new_credit_card_bubble_views.h"
7 #include "base/i18n/rtl.h"
8 #include "chrome/browser/ui/autofill/new_credit_card_bubble_controller.h"
9 #include "chrome/browser/ui/browser_finder.h"
10 #include "chrome/browser/ui/host_desktop.h"
11 #include "chrome/browser/ui/views/frame/browser_view.h"
12 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
13 #include "ui/gfx/insets.h"
14 #include "ui/gfx/size.h"
15 #include "ui/views/bubble/bubble_frame_view.h"
16 #include "ui/views/controls/image_view.h"
17 #include "ui/views/controls/link.h"
18 #include "ui/views/layout/box_layout.h"
19 #include "ui/views/layout/layout_constants.h"
20 #include "ui/views/view.h"
21 #include "ui/views/widget/widget.h"
27 // The space between the bubble and edges of the web contents when showing
28 // without an anchor (e.g. when requestAutocomplete() is called from a popup).
29 const int kAnchorlessEndPadding
= 20;
30 const int kAnchorlessTopPadding
= 10;
32 // Get the view this bubble will be anchored to via |controller|.
33 views::View
* GetAnchor(NewCreditCardBubbleController
* controller
) {
34 Browser
* browser
= chrome::FindTabbedBrowser(controller
->profile(), false,
35 chrome::GetActiveDesktop());
38 BrowserView
* browser_view
= BrowserView::GetBrowserViewForBrowser(browser
);
39 return browser_view
->GetToolbarView()->app_menu();
42 views::BubbleBorder::Arrow
GetArrow(NewCreditCardBubbleController
* controller
) {
43 views::View
* anchor
= GetAnchor(controller
);
44 return anchor
? views::BubbleBorder::TOP_RIGHT
: views::BubbleBorder::NONE
;
49 NewCreditCardBubbleViews::~NewCreditCardBubbleViews() {
50 controller_
->OnBubbleDestroyed();
53 void NewCreditCardBubbleViews::Show() {
54 // TODO(dbeam): investigate why this steals focus from the web contents.
55 views::BubbleDelegateView::CreateBubble(this)->Show();
57 // This bubble doesn't render correctly on Windows without calling
58 // |SizeToContents()|. This must be called after showing the widget.
62 void NewCreditCardBubbleViews::Hide() {
66 gfx::Size
NewCreditCardBubbleViews::GetPreferredSize() {
68 NewCreditCardBubbleView::kContentsWidth
,
69 GetHeightForWidth(NewCreditCardBubbleView::kContentsWidth
));
72 void NewCreditCardBubbleViews::Init() {
73 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0,
74 views::kRelatedControlVerticalSpacing
));
76 views::View
* card_container
= new views::View();
77 card_container
->SetLayoutManager(
78 new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0, 10));
80 views::View
* card_desc_view
= new views::View();
81 card_desc_view
->SetLayoutManager(
82 new views::BoxLayout(views::BoxLayout::kHorizontal
, 0, 0, 10));
84 views::ImageView
* card_icon
= new views::ImageView();
85 const CreditCardDescription
& card_desc
= controller_
->CardDescription();
86 card_icon
->SetImage(card_desc
.icon
.AsImageSkia());
87 card_desc_view
->AddChildView(card_icon
);
89 views::Label
* card_name
= new views::Label(card_desc
.name
);
90 card_name
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
91 card_desc_view
->AddChildView(card_name
);
92 card_container
->AddChildView(card_desc_view
);
94 views::Label
* desc
= new views::Label(card_desc
.description
);
95 desc
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
96 desc
->SetMultiLine(true);
97 card_container
->AddChildView(desc
);
99 AddChildView(card_container
);
101 views::Link
* link
= new views::Link(controller_
->LinkText());
102 link
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
103 link
->set_listener(this);
107 gfx::Rect
NewCreditCardBubbleViews::GetBubbleBounds() {
108 gfx::Rect bounds
= views::BubbleDelegateView::GetBubbleBounds();
112 Browser
* browser
= chrome::FindBrowserWithProfile(controller_
->profile(),
113 chrome::GetActiveDesktop());
116 BrowserView
* browser_view
= BrowserView::GetBrowserViewForBrowser(browser
);
117 views::View
* contents_view
= browser_view
->GetContentsView();
118 gfx::Rect web_contents_bounds
= contents_view
->GetBoundsInScreen();
119 gfx::Insets
border_insets(GetBubbleFrameView()->bubble_border()->GetInsets());
122 if (base::i18n::IsRTL()) {
123 x
= web_contents_bounds
.x() - border_insets
.left() + kAnchorlessEndPadding
;
125 x
= web_contents_bounds
.right() + border_insets
.right();
126 x
-= bounds
.width() + kAnchorlessEndPadding
;
128 int y
= web_contents_bounds
.y() - border_insets
.top() + kAnchorlessTopPadding
;
130 int width
= bounds
.width() - border_insets
.width();
131 int height
= bounds
.height() - border_insets
.height();
133 return gfx::Rect(gfx::Point(x
, y
), gfx::Size(width
, height
));
136 base::string16
NewCreditCardBubbleViews::GetWindowTitle() const {
137 return controller_
->TitleText();
140 void NewCreditCardBubbleViews::LinkClicked(views::Link
* source
,
142 controller_
->OnLinkClicked();
146 base::WeakPtr
<NewCreditCardBubbleView
> NewCreditCardBubbleView::Create(
147 NewCreditCardBubbleController
* controller
) {
148 NewCreditCardBubbleViews
* bubble
= new NewCreditCardBubbleViews(controller
);
149 return bubble
->weak_ptr_factory_
.GetWeakPtr();
152 NewCreditCardBubbleViews::NewCreditCardBubbleViews(
153 NewCreditCardBubbleController
* controller
)
154 : BubbleDelegateView(GetAnchor(controller
), GetArrow(controller
)),
155 controller_(controller
),
156 weak_ptr_factory_(this) {
157 gfx::Insets insets
= views::BubbleFrameView::GetTitleInsets();
158 set_margins(gfx::Insets(0, insets
.left(), insets
.top(), insets
.left()));
161 } // namespace autofill