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

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: leave filllayout alone Created 5 years, 9 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
94 void Layout() override {
sky 2015/02/26 17:18:43 This one shouldn't be const.
Evan Stade 2015/02/26 19:09:41 it's not (?)
95 for (int i = 0; i < child_count(); ++i) {
96 child_at(i)->SetBoundsRect(GetContentsBounds());
97 }
98 }
99
100 gfx::Size GetPreferredSize() const override {
101 if (!has_children())
102 return gfx::Size();
103 gfx::Rect rect(controls_container_->GetPreferredSize());
104 rect.Inset(-host->GetInsets());
sky 2015/02/26 17:18:43 No host.
Evan Stade 2015/02/26 19:09:41 Done.
105 return rect.size();
106 }
107
108 int GetPreferredHeightForWidth(int width) const override {
sky 2015/02/26 17:18:43 GetHeightForWidth.
Evan Stade 2015/02/26 19:09:41 Done.
109 if (!has_children())
110 return 0;
111 const gfx::Insets insets = GetInsets();
112 return controls_container_->GetHeightForWidth(width - insets.width()) +
113 insets.height();
114 }
115
84 void SetInputsEnabled(bool enabled) { 116 void SetInputsEnabled(bool enabled) {
85 cvc_input_->SetEnabled(enabled); 117 cvc_input_->SetEnabled(enabled);
86 118
87 if (month_input_) 119 if (month_input_)
88 month_input_->SetEnabled(enabled); 120 month_input_->SetEnabled(enabled);
89 if (year_input_) 121 if (year_input_)
90 year_input_->SetEnabled(enabled); 122 year_input_->SetEnabled(enabled);
91 } 123 }
92 124
125 void SetInputsInvalid(bool invalid) {
126 cvc_input_->SetInvalid(invalid);
127
128 if (month_input_)
129 month_input_->SetInvalid(invalid);
130 if (year_input_)
131 year_input_->SetInvalid(invalid);
132 }
133
93 // views::DialogDelegateView 134 // views::DialogDelegateView
94 View* GetContentsView() override { 135 View* GetContentsView() override {
95 InitIfNecessary(); 136 InitIfNecessary();
96 return this; 137 return this;
97 } 138 }
98 139
99 // views::View 140 // views::View
100 gfx::Size GetPreferredSize() const override { 141 gfx::Size GetPreferredSize() const override {
101 // Must hardcode a width so the label knows where to wrap. TODO(estade): 142 // 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 143 // This can lead to a weird looking dialog if we end up getting allocated
(...skipping 58 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 SetLayoutManager(new views::CardUnmaskingPromptLayout());
232 controls_container_ = new views::View();
233 controls_container_->SetLayoutManager(
185 new views::BoxLayout(views::BoxLayout::kVertical, 19, 0, 5)); 234 new views::BoxLayout(views::BoxLayout::kVertical, 19, 0, 5));
235 AddChildView(controls_container_);
236
186 views::Label* instructions = 237 views::Label* instructions =
187 new views::Label(controller_->GetInstructionsMessage()); 238 new views::Label(controller_->GetInstructionsMessage());
188 239
189 instructions->SetMultiLine(true); 240 instructions->SetMultiLine(true);
190 instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT); 241 instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT);
191 AddChildView(instructions); 242 controls_container_->AddChildView(instructions);
192 243
193 views::View* input_row = new views::View(); 244 views::View* input_row = new views::View();
194 input_row->SetLayoutManager( 245 input_row->SetLayoutManager(
195 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 5)); 246 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 5));
196 AddChildView(input_row); 247 controls_container_->AddChildView(input_row);
197 248
198 if (controller_->ShouldRequestExpirationDate()) { 249 if (controller_->ShouldRequestExpirationDate()) {
199 month_input_ = new views::Combobox(&month_combobox_model_); 250 month_input_ = new views::Combobox(&month_combobox_model_);
200 month_input_->set_listener(this); 251 month_input_->set_listener(this);
201 input_row->AddChildView(month_input_); 252 input_row->AddChildView(month_input_);
202 year_input_ = new views::Combobox(&year_combobox_model_); 253 year_input_ = new views::Combobox(&year_combobox_model_);
203 year_input_->set_listener(this); 254 year_input_->set_listener(this);
204 input_row->AddChildView(year_input_); 255 input_row->AddChildView(year_input_);
205 } 256 }
206 257
207 cvc_input_ = new DecoratedTextfield( 258 cvc_input_ = new DecoratedTextfield(
208 base::string16(), 259 base::string16(),
209 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC), 260 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC),
210 this); 261 this);
211 cvc_input_->set_default_width_in_chars(10); 262 cvc_input_->set_default_width_in_chars(10);
212 input_row->AddChildView(cvc_input_); 263 input_row->AddChildView(cvc_input_);
213 264
214 views::ImageView* cvc_image = new views::ImageView(); 265 views::ImageView* cvc_image = new views::ImageView();
215 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 266 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
216 267
217 cvc_image->SetImage(rb.GetImageSkiaNamed(controller_->GetCvcImageRid())); 268 cvc_image->SetImage(rb.GetImageSkiaNamed(controller_->GetCvcImageRid()));
218 269
219 input_row->AddChildView(cvc_image); 270 input_row->AddChildView(cvc_image);
220 271
221 message_label_ = new views::Label(); 272 // Reserve vertical space.
222 input_row->AddChildView(message_label_); 273 error_label_ = new views::Label(base::ASCIIToUTF16(" "));
223 message_label_->SetVisible(false); 274 error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
275 error_label_->SetEnabledColor(kWarningColor);
276 controls_container_->AddChildView(error_label_);
224 277
225 storage_checkbox_ = new views::Checkbox(l10n_util::GetStringUTF16( 278 storage_checkbox_ = new views::Checkbox(l10n_util::GetStringUTF16(
226 IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_CHECKBOX)); 279 IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_CHECKBOX));
227 storage_checkbox_->SetChecked(controller_->GetStoreLocallyStartState()); 280 storage_checkbox_->SetChecked(controller_->GetStoreLocallyStartState());
228 AddChildView(storage_checkbox_); 281 controls_container_->AddChildView(storage_checkbox_);
282
283 progress_overlay_ = new views::View();
284 views::BoxLayout* progress_layout =
285 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
286 progress_layout->set_main_axis_alignment(
287 views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
288 progress_layout->set_cross_axis_alignment(
289 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
290 progress_overlay_->SetLayoutManager(progress_layout);
291
292 SkColor bg_color = GetNativeTheme()->
293 GetSystemColor(ui::NativeTheme::kColorId_DialogBackground);
294 bg_color = SkColorSetA(bg_color, 0xDD);
295 progress_overlay_->set_background(
296 views::Background::CreateSolidBackground(bg_color));
297 progress_overlay_->SetVisible(false);
298 AddChildView(progress_overlay_);
299
300 progress_label_ = new views::Label(base::ASCIIToUTF16("Verifying..."));
301 progress_overlay_->AddChildView(progress_label_);
229 } 302 }
230 303
231 void ClosePrompt() { GetWidget()->Close(); } 304 void ClosePrompt() { GetWidget()->Close(); }
232 305
233 CardUnmaskPromptController* controller_; 306 CardUnmaskPromptController* controller_;
234 307
308 views::View* controls_container_;
309
235 DecoratedTextfield* cvc_input_; 310 DecoratedTextfield* cvc_input_;
236 311
237 // These will be null when expiration date is not required. 312 // These will be null when expiration date is not required.
238 views::Combobox* month_input_; 313 views::Combobox* month_input_;
239 views::Combobox* year_input_; 314 views::Combobox* year_input_;
240 315
241 MonthComboboxModel month_combobox_model_; 316 MonthComboboxModel month_combobox_model_;
242 YearComboboxModel year_combobox_model_; 317 YearComboboxModel year_combobox_model_;
243 318
244 // TODO(estade): this is a temporary standin in place of some spinner UI 319 views::Label* error_label_;
245 // as well as a better error message.
246 views::Label* message_label_;
247 320
248 views::Checkbox* storage_checkbox_; 321 views::Checkbox* storage_checkbox_;
249 322
323 views::View* progress_overlay_;
324 views::Label* progress_label_;
325
250 DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViews); 326 DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViews);
251 }; 327 };
252 328
253 } // namespace 329 } // namespace
254 330
255 // static 331 // static
256 CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow( 332 CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow(
257 CardUnmaskPromptController* controller) { 333 CardUnmaskPromptController* controller) {
258 CardUnmaskPromptViews* view = new CardUnmaskPromptViews(controller); 334 CardUnmaskPromptViews* view = new CardUnmaskPromptViews(controller);
259 view->Show(); 335 view->Show();
260 return view; 336 return view;
261 } 337 }
262 338
263 } // namespace autofill 339 } // 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