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 "chrome/browser/ui/views/toolbar/wrench_toolbar_button.h"
14 #include "ui/gfx/geometry/insets.h"
15 #include "ui/gfx/geometry/size.h"
16 #include "ui/views/bubble/bubble_frame_view.h"
17 #include "ui/views/controls/image_view.h"
18 #include "ui/views/controls/link.h"
19 #include "ui/views/layout/box_layout.h"
20 #include "ui/views/layout/layout_constants.h"
21 #include "ui/views/view.h"
22 #include "ui/views/widget/widget.h"
28 // The space between the bubble and edges of the web contents when showing
29 // without an anchor (e.g. when requestAutocomplete() is called from a popup).
30 const int kAnchorlessEndPadding
= 20;
31 const int kAnchorlessTopPadding
= 10;
33 // Get the view this bubble will be anchored to via |controller|.
34 views::View
* GetAnchor(NewCreditCardBubbleController
* controller
) {
35 Browser
* browser
= chrome::FindTabbedBrowser(controller
->profile(), false,
36 chrome::GetActiveDesktop());
39 BrowserView
* browser_view
= BrowserView::GetBrowserViewForBrowser(browser
);
40 return browser_view
->GetToolbarView()->app_menu();
43 views::BubbleBorder::Arrow
GetArrow(NewCreditCardBubbleController
* controller
) {
44 views::View
* anchor
= GetAnchor(controller
);
45 return anchor
? views::BubbleBorder::TOP_RIGHT
: views::BubbleBorder::NONE
;
50 NewCreditCardBubbleViews::~NewCreditCardBubbleViews() {
51 controller_
->OnBubbleDestroyed();
54 void NewCreditCardBubbleViews::Show() {
55 // TODO(dbeam): investigate why this steals focus from the web contents.
56 views::BubbleDelegateView::CreateBubble(this)->Show();
58 // This bubble doesn't render correctly on Windows without calling
59 // |SizeToContents()|. This must be called after showing the widget.
63 void NewCreditCardBubbleViews::Hide() {
67 gfx::Size
NewCreditCardBubbleViews::GetPreferredSize() const {
69 NewCreditCardBubbleView::kContentsWidth
,
70 GetHeightForWidth(NewCreditCardBubbleView::kContentsWidth
));
73 void NewCreditCardBubbleViews::Init() {
74 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0,
75 views::kRelatedControlVerticalSpacing
));
77 views::View
* card_container
= new views::View();
78 card_container
->SetLayoutManager(
79 new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0, 10));
81 views::View
* card_desc_view
= new views::View();
82 card_desc_view
->SetLayoutManager(
83 new views::BoxLayout(views::BoxLayout::kHorizontal
, 0, 0, 10));
85 views::ImageView
* card_icon
= new views::ImageView();
86 const CreditCardDescription
& card_desc
= controller_
->CardDescription();
87 card_icon
->SetImage(card_desc
.icon
.AsImageSkia());
88 card_desc_view
->AddChildView(card_icon
);
90 views::Label
* card_name
= new views::Label(card_desc
.name
);
91 card_name
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
92 card_desc_view
->AddChildView(card_name
);
93 card_container
->AddChildView(card_desc_view
);
95 views::Label
* desc
= new views::Label(card_desc
.description
);
96 desc
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
97 desc
->SetMultiLine(true);
98 card_container
->AddChildView(desc
);
100 AddChildView(card_container
);
102 views::Link
* link
= new views::Link(controller_
->LinkText());
103 link
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
104 link
->set_listener(this);
108 gfx::Rect
NewCreditCardBubbleViews::GetBubbleBounds() {
109 gfx::Rect bounds
= views::BubbleDelegateView::GetBubbleBounds();
113 Browser
* browser
= chrome::FindBrowserWithProfile(controller_
->profile(),
114 chrome::GetActiveDesktop());
117 BrowserView
* browser_view
= BrowserView::GetBrowserViewForBrowser(browser
);
118 views::View
* contents_view
= browser_view
->GetContentsView();
119 gfx::Rect web_contents_bounds
= contents_view
->GetBoundsInScreen();
120 gfx::Insets
border_insets(GetBubbleFrameView()->bubble_border()->GetInsets());
123 if (base::i18n::IsRTL()) {
124 x
= web_contents_bounds
.x() - border_insets
.left() + kAnchorlessEndPadding
;
126 x
= web_contents_bounds
.right() + border_insets
.right();
127 x
-= bounds
.width() + kAnchorlessEndPadding
;
129 int y
= web_contents_bounds
.y() - border_insets
.top() + kAnchorlessTopPadding
;
131 int width
= bounds
.width() - border_insets
.width();
132 int height
= bounds
.height() - border_insets
.height();
134 return gfx::Rect(gfx::Point(x
, y
), gfx::Size(width
, height
));
137 base::string16
NewCreditCardBubbleViews::GetWindowTitle() const {
138 return controller_
->TitleText();
141 void NewCreditCardBubbleViews::LinkClicked(views::Link
* source
,
143 controller_
->OnLinkClicked();
147 base::WeakPtr
<NewCreditCardBubbleView
> NewCreditCardBubbleView::Create(
148 NewCreditCardBubbleController
* controller
) {
149 NewCreditCardBubbleViews
* bubble
= new NewCreditCardBubbleViews(controller
);
150 return bubble
->weak_ptr_factory_
.GetWeakPtr();
153 NewCreditCardBubbleViews::NewCreditCardBubbleViews(
154 NewCreditCardBubbleController
* controller
)
155 : BubbleDelegateView(GetAnchor(controller
), GetArrow(controller
)),
156 controller_(controller
),
157 weak_ptr_factory_(this) {
158 gfx::Insets insets
= views::BubbleFrameView::GetTitleInsets();
159 set_margins(gfx::Insets(0, insets
.left(), insets
.top(), insets
.left()));
162 } // namespace autofill