blob: 3496ec6c27e2d1f99f8118d50d0d51971e27b2c3 [file] [log] [blame]
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001// 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/autocheckout_bubble_views.h"
6
7#include "chrome/browser/ui/autofill/autocheckout_bubble.h"
8#include "chrome/browser/ui/autofill/autocheckout_bubble_controller.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01009#include "ui/gfx/image/image.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000010#include "ui/gfx/rect.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010011#include "ui/views/bubble/bubble_border.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010012#include "ui/views/controls/button/image_button.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000013#include "ui/views/controls/button/label_button.h"
14#include "ui/views/controls/label.h"
15#include "ui/views/layout/grid_layout.h"
16#include "ui/views/layout/layout_constants.h"
17#include "ui/views/widget/widget.h"
18
Ben Murdochbb1529c2013-08-08 10:24:53 +010019#if defined(USE_AURA)
20#include "ui/aura/window.h"
21#endif
22
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000023namespace autofill {
24
25AutocheckoutBubbleViews::AutocheckoutBubbleViews(
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010026 scoped_ptr<AutocheckoutBubbleController> controller,
27 views::View* anchor_view)
28 : views::BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000029 controller_(controller.Pass()),
30 ok_button_(NULL),
31 cancel_button_(NULL) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010032 set_parent_window(controller_->native_window());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000033 controller_->BubbleCreated();
34}
35
36AutocheckoutBubbleViews::~AutocheckoutBubbleViews() {
37 controller_->BubbleDestroyed();
38}
39
40void AutocheckoutBubbleViews::ShowBubble() {
41 StartFade(true);
42}
43
44void AutocheckoutBubbleViews::HideBubble() {
45 StartFade(false);
46}
47
48void AutocheckoutBubbleViews::Init() {
49 views::GridLayout* layout = new views::GridLayout(this);
50 SetLayoutManager(layout);
51
52 // Add the message label to the first row.
53 views::ColumnSet* cs = layout->AddColumnSet(1);
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010054 views::Label* message_label = new views::Label(controller_->PromptText());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000055
56 // Maximum width for the message field in pixels. The message text will be
57 // wrapped when its width is wider than this.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010058 const int kMaxMessageWidth = 300;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000059
60 int message_width =
61 std::min(kMaxMessageWidth, message_label->GetPreferredSize().width());
62 cs->AddColumn(views::GridLayout::LEADING,
63 views::GridLayout::CENTER,
64 0,
65 views::GridLayout::FIXED,
66 message_width,
67 false);
68 message_label->SetBounds(0, 0, message_width, 0);
69 message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
70 message_label->SetMultiLine(true);
71 layout->StartRow(0, 1);
72 layout->AddView(message_label);
73
74 // Padding between message and buttons.
75 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
76
77 cs = layout->AddColumnSet(2);
78 cs->AddPaddingColumn(1, views::kRelatedControlHorizontalSpacing);
79 cs->AddColumn(views::GridLayout::CENTER,
80 views::GridLayout::CENTER,
81 0,
82 views::GridLayout::USE_PREF,
83 0,
84 0);
85 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
86 cs->AddColumn(views::GridLayout::CENTER,
87 views::GridLayout::CENTER,
88 0,
89 views::GridLayout::USE_PREF,
90 0,
91 0);
92 layout->StartRow(0, 2);
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010093
94 if (!controller_->NormalImage().IsEmpty()) {
95 views::ImageButton* image_button = new views::ImageButton(this);
96 image_button->SetImage(views::Button::STATE_NORMAL,
97 controller_->NormalImage().ToImageSkia());
98 image_button->SetImage(views::Button::STATE_HOVERED,
99 controller_->HoverImage().ToImageSkia());
100 image_button->SetImage(views::Button::STATE_PRESSED,
101 controller_->PressedImage().ToImageSkia());
102 ok_button_ = image_button;
103 } else {
104 views::LabelButton* label_button = new views::LabelButton(
105 this, AutocheckoutBubbleController::AcceptText());
106 label_button->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
107 ok_button_ = label_button;
108 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000109 layout->AddView(ok_button_);
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100110
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000111 cancel_button_ =
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100112 new views::LabelButton(this, AutocheckoutBubbleController::CancelText());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000113 cancel_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
114 layout->AddView(cancel_button_);
115}
116
117gfx::Rect AutocheckoutBubbleViews::GetAnchorRect() {
118 return controller_->anchor_rect();
119}
120
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100121void AutocheckoutBubbleViews::OnWidgetBoundsChanged(
122 views::Widget* widget,
123 const gfx::Rect& new_bounds) {
124 if (anchor_widget() == widget)
125 HideBubble();
126}
127
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000128void AutocheckoutBubbleViews::ButtonPressed(views::Button* sender,
129 const ui::Event& event) {
130 if (sender == ok_button_) {
131 controller_->BubbleAccepted();
132 } else if (sender == cancel_button_) {
133 controller_->BubbleCanceled();
134 } else {
135 NOTREACHED();
136 }
137 GetWidget()->Close();
138}
139
140// static
141base::WeakPtr<AutocheckoutBubble> AutocheckoutBubble::Create(
142 scoped_ptr<AutocheckoutBubbleController> controller) {
Ben Murdochbb1529c2013-08-08 10:24:53 +0100143#if defined(USE_AURA)
144 // If the page hasn't yet been attached to a RootWindow,
145 // Aura code for creating the bubble will fail.
146 if (!controller->native_window()->GetRootWindow())
147 return base::WeakPtr<AutocheckoutBubble>();
148#endif // defined(USE_AURA)
149
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100150 views::Widget* widget = views::Widget::GetTopLevelWidgetForNativeView(
151 controller->native_window());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000152 // The bubble owns itself.
153 AutocheckoutBubbleViews* delegate =
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100154 new AutocheckoutBubbleViews(controller.Pass(),
155 widget ? widget->GetContentsView() : NULL);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000156 views::BubbleDelegateView::CreateBubble(delegate);
157 delegate->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
158 return delegate->AsWeakPtr();
159}
160
161} // namespace autofill