Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(548)

Side by Side Diff: chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc

Issue 957523002: Autofill card unmasking prompt - Make "verifying..." message an overlay (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/strings/utf_string_conversions.h" 6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/ui/autofill/autofill_dialog_models.h" 7 #include "chrome/browser/ui/autofill/autofill_dialog_models.h"
8 #include "chrome/browser/ui/autofill/autofill_dialog_types.h"
8 #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" 9 #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h"
9 #include "chrome/browser/ui/autofill/card_unmask_prompt_view.h" 10 #include "chrome/browser/ui/autofill/card_unmask_prompt_view.h"
10 #include "chrome/browser/ui/views/autofill/decorated_textfield.h" 11 #include "chrome/browser/ui/views/autofill/decorated_textfield.h"
11 #include "chrome/grit/generated_resources.h" 12 #include "chrome/grit/generated_resources.h"
12 #include "components/constrained_window/constrained_window_views.h" 13 #include "components/constrained_window/constrained_window_views.h"
13 #include "grit/theme_resources.h" 14 #include "grit/theme_resources.h"
15 #include "third_party/skia/include/core/SkColor.h"
14 #include "ui/base/l10n/l10n_util.h" 16 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/base/resource/resource_bundle.h" 17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/views/background.h"
16 #include "ui/views/controls/button/checkbox.h" 19 #include "ui/views/controls/button/checkbox.h"
17 #include "ui/views/controls/combobox/combobox.h" 20 #include "ui/views/controls/combobox/combobox.h"
18 #include "ui/views/controls/combobox/combobox_listener.h" 21 #include "ui/views/controls/combobox/combobox_listener.h"
19 #include "ui/views/controls/image_view.h" 22 #include "ui/views/controls/image_view.h"
20 #include "ui/views/controls/label.h" 23 #include "ui/views/controls/label.h"
21 #include "ui/views/controls/textfield/textfield_controller.h" 24 #include "ui/views/controls/textfield/textfield_controller.h"
22 #include "ui/views/layout/box_layout.h" 25 #include "ui/views/layout/box_layout.h"
23 #include "ui/views/widget/widget.h" 26 #include "ui/views/widget/widget.h"
24 #include "ui/views/window/dialog_client_view.h" 27 #include "ui/views/window/dialog_client_view.h"
25 #include "ui/views/window/dialog_delegate.h" 28 #include "ui/views/window/dialog_delegate.h"
26 29
27 namespace autofill { 30 namespace autofill {
28 31
29 namespace { 32 namespace {
30 33
31 class CardUnmaskPromptViews : public CardUnmaskPromptView, 34 class CardUnmaskPromptViews : public CardUnmaskPromptView,
32 views::ComboboxListener, 35 views::ComboboxListener,
33 views::DialogDelegateView, 36 views::DialogDelegateView,
34 views::TextfieldController { 37 views::TextfieldController {
35 public: 38 public:
36 explicit CardUnmaskPromptViews(CardUnmaskPromptController* controller) 39 explicit CardUnmaskPromptViews(CardUnmaskPromptController* controller)
37 : controller_(controller), 40 : controller_(controller),
41 controls_container_(nullptr),
38 cvc_input_(nullptr), 42 cvc_input_(nullptr),
39 month_input_(nullptr), 43 month_input_(nullptr),
40 year_input_(nullptr), 44 year_input_(nullptr),
41 message_label_(nullptr), 45 error_label_(nullptr),
42 storage_checkbox_(nullptr) {} 46 storage_checkbox_(nullptr),
47 progress_overlay_(nullptr),
48 progress_label_(nullptr) {}
43 49
44 ~CardUnmaskPromptViews() override { 50 ~CardUnmaskPromptViews() override {
45 if (controller_) 51 if (controller_)
46 controller_->OnUnmaskDialogClosed(); 52 controller_->OnUnmaskDialogClosed();
47 } 53 }
48 54
49 void Show() { 55 void Show() {
50 constrained_window::ShowWebModalDialogViews(this, 56 constrained_window::ShowWebModalDialogViews(this,
51 controller_->GetWebContents()); 57 controller_->GetWebContents());
52 } 58 }
53 59
54 // CardUnmaskPromptView 60 // CardUnmaskPromptView
55 void ControllerGone() override { 61 void ControllerGone() override {
56 controller_ = nullptr; 62 controller_ = nullptr;
57 ClosePrompt(); 63 ClosePrompt();
58 } 64 }
59 65
60 void DisableAndWaitForVerification() override { 66 void DisableAndWaitForVerification() override {
61 SetInputsEnabled(false); 67 SetInputsEnabled(false);
62 message_label_->SetText(base::ASCIIToUTF16("Verifying...")); 68 progress_overlay_->SetVisible(true);
63 message_label_->SetVisible(true);
64 GetDialogClientView()->UpdateDialogButtons(); 69 GetDialogClientView()->UpdateDialogButtons();
65 Layout(); 70 Layout();
66 } 71 }
67 72
68 void GotVerificationResult(bool success) override { 73 void GotVerificationResult(bool success) override {
69 if (success) { 74 if (success) {
70 message_label_->SetText(base::ASCIIToUTF16("Success!")); 75 progress_label_->SetText(base::ASCIIToUTF16("Success!"));
71 base::MessageLoop::current()->PostDelayedTask( 76 base::MessageLoop::current()->PostDelayedTask(
72 FROM_HERE, base::Bind(&CardUnmaskPromptViews::ClosePrompt, 77 FROM_HERE, base::Bind(&CardUnmaskPromptViews::ClosePrompt,
73 base::Unretained(this)), 78 base::Unretained(this)),
74 base::TimeDelta::FromSeconds(1)); 79 base::TimeDelta::FromSeconds(1));
75 } else { 80 } else {
76 SetInputsEnabled(true); 81 SetInputsEnabled(true);
77 cvc_input_->SetInvalid(true); 82 SetInputsInvalid(true);
78 message_label_->SetText(base::ASCIIToUTF16("Verification error.")); 83 // TODO(estade): it's somewhat jarring when the error comes back too
84 // quickly.
85 progress_overlay_->SetVisible(false);
86 // TODO(estade): When do we hide |error_label_|?
87 error_label_->SetText(
88 base::ASCIIToUTF16("Verification error. Please try again."));
79 GetDialogClientView()->UpdateDialogButtons(); 89 GetDialogClientView()->UpdateDialogButtons();
80 } 90 }
81 Layout(); 91 Layout();
82 } 92 }
83 93
84 void SetInputsEnabled(bool enabled) { 94 void SetInputsEnabled(bool enabled) {
85 cvc_input_->SetEnabled(enabled); 95 cvc_input_->SetEnabled(enabled);
86 96
87 if (month_input_) 97 if (month_input_)
88 month_input_->SetEnabled(enabled); 98 month_input_->SetEnabled(enabled);
89 if (year_input_) 99 if (year_input_)
90 year_input_->SetEnabled(enabled); 100 year_input_->SetEnabled(enabled);
91 } 101 }
92 102
103 void SetInputsInvalid(bool invalid) {
104 cvc_input_->SetInvalid(invalid);
105
106 if (month_input_)
107 month_input_->SetInvalid(invalid);
108 if (year_input_)
109 year_input_->SetInvalid(invalid);
110 }
111
93 // views::DialogDelegateView 112 // views::DialogDelegateView
94 View* GetContentsView() override { 113 View* GetContentsView() override {
95 InitIfNecessary(); 114 InitIfNecessary();
96 return this; 115 return this;
97 } 116 }
98 117
99 // views::View 118 // views::View
100 gfx::Size GetPreferredSize() const override { 119 gfx::Size GetPreferredSize() const override {
101 // Must hardcode a width so the label knows where to wrap. TODO(estade): 120 // Must hardcode a width so the label knows where to wrap. TODO(estade):
102 // This can lead to a weird looking dialog if we end up getting allocated 121 // This can lead to a weird looking dialog if we end up getting allocated
103 // more width than we ask for, e.g. if the title is super long. 122 // more width than we ask for, e.g. if the title is super long.
104 const int kWidth = 250; 123 const int kWidth = 250;
105 return gfx::Size(kWidth, GetHeightForWidth(kWidth)); 124 return gfx::Size(kWidth, GetHeightForWidth(kWidth));
106 } 125 }
107 126
127 void Layout() override {
128 for (int i = 0; i < child_count(); ++i) {
129 child_at(i)->SetBoundsRect(GetContentsBounds());
130 }
131 }
132
133 int GetHeightForWidth(int width) const override {
134 if (!has_children())
135 return 0;
136 const gfx::Insets insets = GetInsets();
137 return controls_container_->GetHeightForWidth(width - insets.width()) +
138 insets.height();
139 }
140
141 void OnNativeThemeChanged(const ui::NativeTheme* theme) override {
142 SkColor bg_color =
143 theme->GetSystemColor(ui::NativeTheme::kColorId_DialogBackground);
144 bg_color = SkColorSetA(bg_color, 0xDD);
145 progress_overlay_->set_background(
146 views::Background::CreateSolidBackground(bg_color));
147 }
148
108 ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; } 149 ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; }
109 150
110 base::string16 GetWindowTitle() const override { 151 base::string16 GetWindowTitle() const override {
111 return controller_->GetWindowTitle(); 152 return controller_->GetWindowTitle();
112 } 153 }
113 154
114 void DeleteDelegate() override { delete this; } 155 void DeleteDelegate() override { delete this; }
115 156
116 int GetDialogButtons() const override { 157 int GetDialogButtons() const override {
117 return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL; 158 return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 year_input_ 202 year_input_
162 ? year_combobox_model_.GetItemAt(year_input_->selected_index()) 203 ? year_combobox_model_.GetItemAt(year_input_->selected_index())
163 : base::string16(), 204 : base::string16(),
164 storage_checkbox_ ? storage_checkbox_->checked() : false); 205 storage_checkbox_ ? storage_checkbox_->checked() : false);
165 return false; 206 return false;
166 } 207 }
167 208
168 // views::TextfieldController 209 // views::TextfieldController
169 void ContentsChanged(views::Textfield* sender, 210 void ContentsChanged(views::Textfield* sender,
170 const base::string16& new_contents) override { 211 const base::string16& new_contents) override {
212 // Sets all inputs back to valid since we don't know which one was
213 // actually invalid to begin with.
214 SetInputsInvalid(false);
171 GetDialogClientView()->UpdateDialogButtons(); 215 GetDialogClientView()->UpdateDialogButtons();
172 } 216 }
173 217
174 // views::ComboboxListener 218 // views::ComboboxListener
175 void OnPerformAction(views::Combobox* combobox) override { 219 void OnPerformAction(views::Combobox* combobox) override {
220 // Sets all inputs back to valid since we don't know which one was
221 // actually invalid to begin with.
222 SetInputsInvalid(false);
176 GetDialogClientView()->UpdateDialogButtons(); 223 GetDialogClientView()->UpdateDialogButtons();
177 } 224 }
178 225
179 private: 226 private:
180 void InitIfNecessary() { 227 void InitIfNecessary() {
181 if (has_children()) 228 if (has_children())
182 return; 229 return;
183 230
184 SetLayoutManager( 231 controls_container_ = new views::View();
232 controls_container_->SetLayoutManager(
185 new views::BoxLayout(views::BoxLayout::kVertical, 19, 0, 5)); 233 new views::BoxLayout(views::BoxLayout::kVertical, 19, 0, 5));
234 AddChildView(controls_container_);
235
186 views::Label* instructions = 236 views::Label* instructions =
187 new views::Label(controller_->GetInstructionsMessage()); 237 new views::Label(controller_->GetInstructionsMessage());
188 238
189 instructions->SetMultiLine(true); 239 instructions->SetMultiLine(true);
190 instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT); 240 instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT);
191 AddChildView(instructions); 241 controls_container_->AddChildView(instructions);
192 242
193 views::View* input_row = new views::View(); 243 views::View* input_row = new views::View();
194 input_row->SetLayoutManager( 244 input_row->SetLayoutManager(
195 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 5)); 245 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 5));
196 AddChildView(input_row); 246 controls_container_->AddChildView(input_row);
197 247
198 if (controller_->ShouldRequestExpirationDate()) { 248 if (controller_->ShouldRequestExpirationDate()) {
199 month_input_ = new views::Combobox(&month_combobox_model_); 249 month_input_ = new views::Combobox(&month_combobox_model_);
200 month_input_->set_listener(this); 250 month_input_->set_listener(this);
201 input_row->AddChildView(month_input_); 251 input_row->AddChildView(month_input_);
202 year_input_ = new views::Combobox(&year_combobox_model_); 252 year_input_ = new views::Combobox(&year_combobox_model_);
203 year_input_->set_listener(this); 253 year_input_->set_listener(this);
204 input_row->AddChildView(year_input_); 254 input_row->AddChildView(year_input_);
205 } 255 }
206 256
207 cvc_input_ = new DecoratedTextfield( 257 cvc_input_ = new DecoratedTextfield(
208 base::string16(), 258 base::string16(),
209 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC), 259 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC),
210 this); 260 this);
211 cvc_input_->set_default_width_in_chars(10); 261 cvc_input_->set_default_width_in_chars(10);
212 input_row->AddChildView(cvc_input_); 262 input_row->AddChildView(cvc_input_);
213 263
214 views::ImageView* cvc_image = new views::ImageView(); 264 views::ImageView* cvc_image = new views::ImageView();
215 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 265 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
216 266
217 cvc_image->SetImage(rb.GetImageSkiaNamed(controller_->GetCvcImageRid())); 267 cvc_image->SetImage(rb.GetImageSkiaNamed(controller_->GetCvcImageRid()));
218 268
219 input_row->AddChildView(cvc_image); 269 input_row->AddChildView(cvc_image);
220 270
221 message_label_ = new views::Label(); 271 // Reserve vertical space.
222 input_row->AddChildView(message_label_); 272 error_label_ = new views::Label(base::ASCIIToUTF16(" "));
223 message_label_->SetVisible(false); 273 error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
274 error_label_->SetEnabledColor(kWarningColor);
275 controls_container_->AddChildView(error_label_);
224 276
225 storage_checkbox_ = new views::Checkbox(l10n_util::GetStringUTF16( 277 storage_checkbox_ = new views::Checkbox(l10n_util::GetStringUTF16(
226 IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_CHECKBOX)); 278 IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_CHECKBOX));
227 storage_checkbox_->SetChecked(controller_->GetStoreLocallyStartState()); 279 storage_checkbox_->SetChecked(controller_->GetStoreLocallyStartState());
228 AddChildView(storage_checkbox_); 280 controls_container_->AddChildView(storage_checkbox_);
281
282 progress_overlay_ = new views::View();
283 views::BoxLayout* progress_layout =
284 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
285 progress_layout->set_main_axis_alignment(
286 views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
287 progress_layout->set_cross_axis_alignment(
288 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
289 progress_overlay_->SetLayoutManager(progress_layout);
290
291 progress_overlay_->SetVisible(false);
292 AddChildView(progress_overlay_);
293
294 progress_label_ = new views::Label(base::ASCIIToUTF16("Verifying..."));
295 progress_overlay_->AddChildView(progress_label_);
229 } 296 }
230 297
231 void ClosePrompt() { GetWidget()->Close(); } 298 void ClosePrompt() { GetWidget()->Close(); }
232 299
233 CardUnmaskPromptController* controller_; 300 CardUnmaskPromptController* controller_;
234 301
302 views::View* controls_container_;
303
235 DecoratedTextfield* cvc_input_; 304 DecoratedTextfield* cvc_input_;
236 305
237 // These will be null when expiration date is not required. 306 // These will be null when expiration date is not required.
238 views::Combobox* month_input_; 307 views::Combobox* month_input_;
239 views::Combobox* year_input_; 308 views::Combobox* year_input_;
240 309
241 MonthComboboxModel month_combobox_model_; 310 MonthComboboxModel month_combobox_model_;
242 YearComboboxModel year_combobox_model_; 311 YearComboboxModel year_combobox_model_;
243 312
244 // TODO(estade): this is a temporary standin in place of some spinner UI 313 views::Label* error_label_;
245 // as well as a better error message.
246 views::Label* message_label_;
247 314
248 views::Checkbox* storage_checkbox_; 315 views::Checkbox* storage_checkbox_;
249 316
317 views::View* progress_overlay_;
318 views::Label* progress_label_;
319
250 DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViews); 320 DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViews);
251 }; 321 };
252 322
253 } // namespace 323 } // namespace
254 324
255 // static 325 // static
256 CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow( 326 CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow(
257 CardUnmaskPromptController* controller) { 327 CardUnmaskPromptController* controller) {
258 CardUnmaskPromptViews* view = new CardUnmaskPromptViews(controller); 328 CardUnmaskPromptViews* view = new CardUnmaskPromptViews(controller);
259 view->Show(); 329 view->Show();
260 return view; 330 return view;
261 } 331 }
262 332
263 } // namespace autofill 333 } // namespace autofill
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698