new_credit_card_bubble_views.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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. 4 5#include "chrome/browser/ui/views/autofill/new_credit_card_bubble_views.h" 6 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" 22 23namespace autofill { 24 25namespace { 26 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). 29const int kAnchorlessEndPadding = 20; 30const int kAnchorlessTopPadding = 10; 31 32// Get the view this bubble will be anchored to via |controller|. 33views::View* GetAnchor(NewCreditCardBubbleController* controller) { 34 Browser* browser = chrome::FindTabbedBrowser(controller->profile(), false, 35 chrome::GetActiveDesktop()); 36 if (!browser) 37 return NULL; 38 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); 39 return browser_view->GetToolbarView()->app_menu(); 40} 41 42views::BubbleBorder::Arrow GetArrow(NewCreditCardBubbleController* controller) { 43 views::View* anchor = GetAnchor(controller); 44 return anchor ? views::BubbleBorder::TOP_RIGHT : views::BubbleBorder::NONE; 45} 46 47} // namespace 48 49NewCreditCardBubbleViews::~NewCreditCardBubbleViews() { 50 controller_->OnBubbleDestroyed(); 51} 52 53void NewCreditCardBubbleViews::Show() { 54 // TODO(dbeam): investigate why this steals focus from the web contents. 55 views::BubbleDelegateView::CreateBubble(this)->Show(); 56 57 // This bubble doesn't render correctly on Windows without calling 58 // |SizeToContents()|. This must be called after showing the widget. 59 SizeToContents(); 60} 61 62void NewCreditCardBubbleViews::Hide() { 63 GetWidget()->Close(); 64} 65 66gfx::Size NewCreditCardBubbleViews::GetPreferredSize() const { 67 return gfx::Size( 68 NewCreditCardBubbleView::kContentsWidth, 69 GetHeightForWidth(NewCreditCardBubbleView::kContentsWidth)); 70} 71 72void NewCreditCardBubbleViews::Init() { 73 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 74 views::kRelatedControlVerticalSpacing)); 75 76 views::View* card_container = new views::View(); 77 card_container->SetLayoutManager( 78 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 10)); 79 80 views::View* card_desc_view = new views::View(); 81 card_desc_view->SetLayoutManager( 82 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 10)); 83 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); 88 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); 93 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); 98 99 AddChildView(card_container); 100 101 views::Link* link = new views::Link(controller_->LinkText()); 102 link->SetHorizontalAlignment(gfx::ALIGN_LEFT); 103 link->set_listener(this); 104 AddChildView(link); 105} 106 107gfx::Rect NewCreditCardBubbleViews::GetBubbleBounds() { 108 gfx::Rect bounds = views::BubbleDelegateView::GetBubbleBounds(); 109 if (GetAnchorView()) 110 return bounds; 111 112 Browser* browser = chrome::FindBrowserWithProfile(controller_->profile(), 113 chrome::GetActiveDesktop()); 114 DCHECK(browser); 115 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()); 120 121 int x; 122 if (base::i18n::IsRTL()) { 123 x = web_contents_bounds.x() - border_insets.left() + kAnchorlessEndPadding; 124 } else { 125 x = web_contents_bounds.right() + border_insets.right(); 126 x -= bounds.width() + kAnchorlessEndPadding; 127 } 128 int y = web_contents_bounds.y() - border_insets.top() + kAnchorlessTopPadding; 129 130 int width = bounds.width() - border_insets.width(); 131 int height = bounds.height() - border_insets.height(); 132 133 return gfx::Rect(gfx::Point(x, y), gfx::Size(width, height)); 134} 135 136base::string16 NewCreditCardBubbleViews::GetWindowTitle() const { 137 return controller_->TitleText(); 138} 139 140void NewCreditCardBubbleViews::LinkClicked(views::Link* source, 141 int event_flags) { 142 controller_->OnLinkClicked(); 143} 144 145// static 146base::WeakPtr<NewCreditCardBubbleView> NewCreditCardBubbleView::Create( 147 NewCreditCardBubbleController* controller) { 148 NewCreditCardBubbleViews* bubble = new NewCreditCardBubbleViews(controller); 149 return bubble->weak_ptr_factory_.GetWeakPtr(); 150} 151 152NewCreditCardBubbleViews::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())); 159} 160 161} // namespace autofill 162