1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// found in the LICENSE file.
4ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
5ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/ui/views/autofill/new_credit_card_bubble_views.h"
6ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/i18n/rtl.h"
8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/ui/autofill/new_credit_card_bubble_controller.h"
9ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/ui/browser_finder.h"
10ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/ui/host_desktop.h"
11ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/ui/views/frame/browser_view.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
13ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/gfx/insets.h"
14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/gfx/size.h"
15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/views/bubble/bubble_frame_view.h"
16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/views/controls/image_view.h"
17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/views/controls/link.h"
18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/views/layout/box_layout.h"
19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/views/layout/layout_constants.h"
20ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/views/view.h"
21ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/views/widget/widget.h"
22ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace autofill {
24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace {
26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The space between the bubble and edges of the web contents when showing
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// without an anchor (e.g. when requestAutocomplete() is called from a popup).
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const int kAnchorlessEndPadding = 20;
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const int kAnchorlessTopPadding = 10;
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
32ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Get the view this bubble will be anchored to via |controller|.
33ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochviews::View* GetAnchor(NewCreditCardBubbleController* controller) {
34ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  Browser* browser = chrome::FindTabbedBrowser(controller->profile(), false,
35ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                               chrome::GetActiveDesktop());
36ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!browser)
37ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return NULL;
38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return browser_view->GetToolbarView()->app_menu();
40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)views::BubbleBorder::Arrow GetArrow(NewCreditCardBubbleController* controller) {
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  views::View* anchor = GetAnchor(controller);
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return anchor ? views::BubbleBorder::TOP_RIGHT : views::BubbleBorder::NONE;
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace
48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochNewCreditCardBubbleViews::~NewCreditCardBubbleViews() {
50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  controller_->OnBubbleDestroyed();
51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid NewCreditCardBubbleViews::Show() {
54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // TODO(dbeam): investigate why this steals focus from the web contents.
55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  views::BubbleDelegateView::CreateBubble(this)->Show();
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // This bubble doesn't render correctly on Windows without calling
58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // |SizeToContents()|. This must be called after showing the widget.
59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SizeToContents();
60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid NewCreditCardBubbleViews::Hide() {
63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GetWidget()->Close();
64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size NewCreditCardBubbleViews::GetPreferredSize() const {
67ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return gfx::Size(
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      NewCreditCardBubbleView::kContentsWidth,
69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      GetHeightForWidth(NewCreditCardBubbleView::kContentsWidth));
70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid NewCreditCardBubbleViews::Init() {
73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0,
74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                        views::kRelatedControlVerticalSpacing));
75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  views::View* card_container = new views::View();
77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  card_container->SetLayoutManager(
78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 10));
79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  views::View* card_desc_view = new views::View();
81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  card_desc_view->SetLayoutManager(
82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 10));
83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  views::ImageView* card_icon = new views::ImageView();
85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const CreditCardDescription& card_desc = controller_->CardDescription();
86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  card_icon->SetImage(card_desc.icon.AsImageSkia());
87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  card_desc_view->AddChildView(card_icon);
88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  views::Label* card_name = new views::Label(card_desc.name);
90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  card_name->SetHorizontalAlignment(gfx::ALIGN_LEFT);
91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  card_desc_view->AddChildView(card_name);
92ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  card_container->AddChildView(card_desc_view);
93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  views::Label* desc = new views::Label(card_desc.description);
95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  desc->SetHorizontalAlignment(gfx::ALIGN_LEFT);
96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  desc->SetMultiLine(true);
97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  card_container->AddChildView(desc);
98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  AddChildView(card_container);
100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  views::Link* link = new views::Link(controller_->LinkText());
102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  link->SetHorizontalAlignment(gfx::ALIGN_LEFT);
103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  link->set_listener(this);
104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  AddChildView(link);
105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)gfx::Rect NewCreditCardBubbleViews::GetBubbleBounds() {
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Rect bounds = views::BubbleDelegateView::GetBubbleBounds();
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (GetAnchorView())
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return bounds;
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Browser* browser = chrome::FindBrowserWithProfile(controller_->profile(),
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                    chrome::GetActiveDesktop());
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(browser);
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  views::View* contents_view = browser_view->GetContentsView();
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Rect web_contents_bounds = contents_view->GetBoundsInScreen();
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Insets border_insets(GetBubbleFrameView()->bubble_border()->GetInsets());
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int x;
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (base::i18n::IsRTL()) {
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    x = web_contents_bounds.x() - border_insets.left() + kAnchorlessEndPadding;
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    x = web_contents_bounds.right() + border_insets.right();
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    x -= bounds.width() + kAnchorlessEndPadding;
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int y = web_contents_bounds.y() - border_insets.top() + kAnchorlessTopPadding;
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int width = bounds.width() - border_insets.width();
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int height = bounds.height() - border_insets.height();
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return gfx::Rect(gfx::Point(x, y), gfx::Size(width, height));
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbase::string16 NewCreditCardBubbleViews::GetWindowTitle() const {
137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return controller_->TitleText();
138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid NewCreditCardBubbleViews::LinkClicked(views::Link* source,
141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                           int event_flags) {
142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  controller_->OnLinkClicked();
143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static
146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbase::WeakPtr<NewCreditCardBubbleView> NewCreditCardBubbleView::Create(
147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    NewCreditCardBubbleController* controller) {
148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  NewCreditCardBubbleViews* bubble = new NewCreditCardBubbleViews(controller);
149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return bubble->weak_ptr_factory_.GetWeakPtr();
150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochNewCreditCardBubbleViews::NewCreditCardBubbleViews(
153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    NewCreditCardBubbleController* controller)
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : BubbleDelegateView(GetAnchor(controller), GetArrow(controller)),
155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      controller_(controller),
156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      weak_ptr_factory_(this) {
157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  gfx::Insets insets = views::BubbleFrameView::GetTitleInsets();
158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  set_margins(gfx::Insets(0, insets.left(), insets.top(), insets.left()));
159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace autofill
162