| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/ui/autofill/autofill_popup_controller_impl.h" | 5 #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 12 #include "chrome/browser/ui/autofill/autofill_popup_delegate.h" | 12 #include "chrome/browser/ui/autofill/autofill_popup_delegate.h" |
| 13 #include "chrome/browser/ui/autofill/autofill_popup_view.h" | 13 #include "chrome/browser/ui/autofill/autofill_popup_view.h" |
| 14 #include "content/public/browser/native_web_keyboard_event.h" | 14 #include "content/public/browser/native_web_keyboard_event.h" |
| 15 #include "grit/webkit_resources.h" | 15 #include "grit/webkit_resources.h" |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h" |
| 17 #include "ui/base/events/event.h" | 17 #include "ui/base/events/event.h" |
| 18 #include "ui/base/text/text_elider.h" | 18 #include "ui/base/text/text_elider.h" |
| 19 #include "ui/gfx/display.h" | 19 #include "ui/gfx/display.h" |
| 20 #include "ui/gfx/screen.h" | 20 #include "ui/gfx/screen.h" |
| 21 #include "ui/gfx/vector2d.h" | 21 #include "ui/gfx/vector2d.h" |
| 22 | 22 |
| 23 using base::WeakPtr; |
| 23 using WebKit::WebAutofillClient; | 24 using WebKit::WebAutofillClient; |
| 24 | 25 |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| 27 // Used to indicate that no line is currently selected by the user. | 28 // Used to indicate that no line is currently selected by the user. |
| 28 const int kNoSelection = -1; | 29 const int kNoSelection = -1; |
| 29 | 30 |
| 30 // Size difference between name and subtext in pixels. | 31 // Size difference between name and subtext in pixels. |
| 31 const int kLabelFontSizeDelta = -2; | 32 const int kLabelFontSizeDelta = -2; |
| 32 | 33 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 63 { "genericCC", IDR_AUTOFILL_CC_GENERIC }, | 64 { "genericCC", IDR_AUTOFILL_CC_GENERIC }, |
| 64 { "jcbCC", IDR_AUTOFILL_CC_JCB }, | 65 { "jcbCC", IDR_AUTOFILL_CC_JCB }, |
| 65 { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD }, | 66 { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD }, |
| 66 { "soloCC", IDR_AUTOFILL_CC_SOLO }, | 67 { "soloCC", IDR_AUTOFILL_CC_SOLO }, |
| 67 { "visaCC", IDR_AUTOFILL_CC_VISA }, | 68 { "visaCC", IDR_AUTOFILL_CC_VISA }, |
| 68 }; | 69 }; |
| 69 | 70 |
| 70 } // end namespace | 71 } // end namespace |
| 71 | 72 |
| 72 // static | 73 // static |
| 73 AutofillPopupControllerImpl* AutofillPopupControllerImpl::GetOrCreate( | 74 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetOrCreate( |
| 74 AutofillPopupControllerImpl* previous, | 75 WeakPtr<AutofillPopupControllerImpl> previous, |
| 75 AutofillPopupDelegate* delegate, | 76 AutofillPopupDelegate* delegate, |
| 76 gfx::NativeView container_view, | 77 gfx::NativeView container_view, |
| 77 const gfx::Rect& element_bounds) { | 78 const gfx::Rect& element_bounds) { |
| 78 DCHECK(!previous || previous->delegate_ == delegate); | 79 DCHECK(!previous || previous->delegate_ == delegate); |
| 79 | 80 |
| 80 if (previous && | 81 if (previous && |
| 81 previous->container_view() == container_view && | 82 previous->container_view() == container_view && |
| 82 previous->element_bounds() == element_bounds) { | 83 previous->element_bounds() == element_bounds) { |
| 83 return previous; | 84 return previous; |
| 84 } | 85 } |
| 85 | 86 |
| 86 if (previous) | 87 if (previous) |
| 87 previous->Hide(); | 88 previous->Hide(); |
| 88 | 89 |
| 89 return new AutofillPopupControllerImpl( | 90 AutofillPopupControllerImpl* controller = |
| 90 delegate, container_view, element_bounds); | 91 new AutofillPopupControllerImpl(delegate, container_view, element_bounds); |
| 92 return controller->GetWeakPtr(); |
| 91 } | 93 } |
| 92 | 94 |
| 93 AutofillPopupControllerImpl::AutofillPopupControllerImpl( | 95 AutofillPopupControllerImpl::AutofillPopupControllerImpl( |
| 94 AutofillPopupDelegate* delegate, | 96 AutofillPopupDelegate* delegate, |
| 95 gfx::NativeView container_view, | 97 gfx::NativeView container_view, |
| 96 const gfx::Rect& element_bounds) | 98 const gfx::Rect& element_bounds) |
| 97 : view_(NULL), | 99 : view_(NULL), |
| 98 delegate_(delegate), | 100 delegate_(delegate), |
| 99 container_view_(container_view), | 101 container_view_(container_view), |
| 100 element_bounds_(element_bounds), | 102 element_bounds_(element_bounds), |
| 101 selected_line_(kNoSelection), | 103 selected_line_(kNoSelection), |
| 102 delete_icon_hovered_(false), | 104 delete_icon_hovered_(false), |
| 103 is_hiding_(false), | 105 is_hiding_(false), |
| 104 inform_delegate_of_destruction_(true) { | 106 weak_ptr_factory_(this) { |
| 105 #if !defined(OS_ANDROID) | 107 #if !defined(OS_ANDROID) |
| 106 subtext_font_ = name_font_.DeriveFont(kLabelFontSizeDelta); | 108 subtext_font_ = name_font_.DeriveFont(kLabelFontSizeDelta); |
| 107 #endif | 109 #endif |
| 108 } | 110 } |
| 109 | 111 |
| 110 AutofillPopupControllerImpl::~AutofillPopupControllerImpl() { | 112 AutofillPopupControllerImpl::~AutofillPopupControllerImpl() {} |
| 111 if (inform_delegate_of_destruction_) | |
| 112 delegate_->ControllerDestroyed(); | |
| 113 } | |
| 114 | 113 |
| 115 void AutofillPopupControllerImpl::Show( | 114 void AutofillPopupControllerImpl::Show( |
| 116 const std::vector<string16>& names, | 115 const std::vector<string16>& names, |
| 117 const std::vector<string16>& subtexts, | 116 const std::vector<string16>& subtexts, |
| 118 const std::vector<string16>& icons, | 117 const std::vector<string16>& icons, |
| 119 const std::vector<int>& identifiers) { | 118 const std::vector<int>& identifiers) { |
| 120 names_ = names; | 119 names_ = names; |
| 121 full_names_ = names; | 120 full_names_ = names; |
| 122 subtexts_ = subtexts; | 121 subtexts_ = subtexts; |
| 123 icons_ = icons; | 122 icons_ = icons; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 ui::ELIDE_AT_END); | 156 ui::ELIDE_AT_END); |
| 158 } | 157 } |
| 159 #endif | 158 #endif |
| 160 | 159 |
| 161 if (!view_) { | 160 if (!view_) { |
| 162 view_ = AutofillPopupView::Create(this); | 161 view_ = AutofillPopupView::Create(this); |
| 163 ShowView(); | 162 ShowView(); |
| 164 } else { | 163 } else { |
| 165 UpdateBoundsAndRedrawPopup(); | 164 UpdateBoundsAndRedrawPopup(); |
| 166 } | 165 } |
| 166 |
| 167 delegate_->OnPopupShown(this); |
| 167 } | 168 } |
| 168 | 169 |
| 169 void AutofillPopupControllerImpl::Hide() { | 170 void AutofillPopupControllerImpl::Hide() { |
| 170 inform_delegate_of_destruction_ = false; | 171 if (is_hiding_) |
| 171 HideInternal(); | 172 return; |
| 173 is_hiding_ = true; |
| 174 |
| 175 SetSelectedLine(kNoSelection); |
| 176 |
| 177 delegate_->OnPopupHidden(this); |
| 178 |
| 179 if (view_) |
| 180 view_->Hide(); |
| 181 else |
| 182 delete this; |
| 172 } | 183 } |
| 173 | 184 |
| 174 bool AutofillPopupControllerImpl::HandleKeyPressEvent( | 185 bool AutofillPopupControllerImpl::HandleKeyPressEvent( |
| 175 const content::NativeWebKeyboardEvent& event) { | 186 const content::NativeWebKeyboardEvent& event) { |
| 176 switch (event.windowsKeyCode) { | 187 switch (event.windowsKeyCode) { |
| 177 case ui::VKEY_UP: | 188 case ui::VKEY_UP: |
| 178 SelectPreviousLine(); | 189 SelectPreviousLine(); |
| 179 return true; | 190 return true; |
| 180 case ui::VKEY_DOWN: | 191 case ui::VKEY_DOWN: |
| 181 SelectNextLine(); | 192 SelectNextLine(); |
| 182 return true; | 193 return true; |
| 183 case ui::VKEY_PRIOR: // Page up. | 194 case ui::VKEY_PRIOR: // Page up. |
| 184 SetSelectedLine(0); | 195 SetSelectedLine(0); |
| 185 return true; | 196 return true; |
| 186 case ui::VKEY_NEXT: // Page down. | 197 case ui::VKEY_NEXT: // Page down. |
| 187 SetSelectedLine(names().size() - 1); | 198 SetSelectedLine(names().size() - 1); |
| 188 return true; | 199 return true; |
| 189 case ui::VKEY_ESCAPE: | 200 case ui::VKEY_ESCAPE: |
| 190 HideInternal(); | 201 Hide(); |
| 191 return true; | 202 return true; |
| 192 case ui::VKEY_DELETE: | 203 case ui::VKEY_DELETE: |
| 193 return (event.modifiers & content::NativeWebKeyboardEvent::ShiftKey) && | 204 return (event.modifiers & content::NativeWebKeyboardEvent::ShiftKey) && |
| 194 RemoveSelectedLine(); | 205 RemoveSelectedLine(); |
| 195 case ui::VKEY_RETURN: | 206 case ui::VKEY_RETURN: |
| 196 return AcceptSelectedLine(); | 207 return AcceptSelectedLine(); |
| 197 default: | 208 default: |
| 198 return false; | 209 return false; |
| 199 } | 210 } |
| 200 } | 211 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 #endif | 329 #endif |
| 319 | 330 |
| 320 int AutofillPopupControllerImpl::selected_line() const { | 331 int AutofillPopupControllerImpl::selected_line() const { |
| 321 return selected_line_; | 332 return selected_line_; |
| 322 } | 333 } |
| 323 | 334 |
| 324 bool AutofillPopupControllerImpl::delete_icon_hovered() const { | 335 bool AutofillPopupControllerImpl::delete_icon_hovered() const { |
| 325 return delete_icon_hovered_; | 336 return delete_icon_hovered_; |
| 326 } | 337 } |
| 327 | 338 |
| 328 void AutofillPopupControllerImpl::HideInternal() { | |
| 329 if (is_hiding_) | |
| 330 return; | |
| 331 is_hiding_ = true; | |
| 332 | |
| 333 SetSelectedLine(kNoSelection); | |
| 334 | |
| 335 if (view_) | |
| 336 view_->Hide(); | |
| 337 else | |
| 338 delete this; | |
| 339 } | |
| 340 | |
| 341 void AutofillPopupControllerImpl::SetSelectedLine(int selected_line) { | 339 void AutofillPopupControllerImpl::SetSelectedLine(int selected_line) { |
| 342 if (selected_line_ == selected_line) | 340 if (selected_line_ == selected_line) |
| 343 return; | 341 return; |
| 344 | 342 |
| 345 if (selected_line_ != kNoSelection) | 343 if (selected_line_ != kNoSelection) |
| 346 InvalidateRow(selected_line_); | 344 InvalidateRow(selected_line_); |
| 347 | 345 |
| 348 if (selected_line != kNoSelection) | 346 if (selected_line != kNoSelection) |
| 349 InvalidateRow(selected_line); | 347 InvalidateRow(selected_line); |
| 350 | 348 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 subtexts_.erase(subtexts_.begin() + selected_line_); | 417 subtexts_.erase(subtexts_.begin() + selected_line_); |
| 420 icons_.erase(icons_.begin() + selected_line_); | 418 icons_.erase(icons_.begin() + selected_line_); |
| 421 identifiers_.erase(identifiers_.begin() + selected_line_); | 419 identifiers_.erase(identifiers_.begin() + selected_line_); |
| 422 | 420 |
| 423 SetSelectedLine(kNoSelection); | 421 SetSelectedLine(kNoSelection); |
| 424 | 422 |
| 425 if (HasSuggestions()) { | 423 if (HasSuggestions()) { |
| 426 delegate_->ClearPreviewedForm(); | 424 delegate_->ClearPreviewedForm(); |
| 427 UpdateBoundsAndRedrawPopup(); | 425 UpdateBoundsAndRedrawPopup(); |
| 428 } else { | 426 } else { |
| 429 HideInternal(); | 427 Hide(); |
| 430 } | 428 } |
| 431 | 429 |
| 432 return true; | 430 return true; |
| 433 } | 431 } |
| 434 | 432 |
| 435 int AutofillPopupControllerImpl::LineFromY(int y) { | 433 int AutofillPopupControllerImpl::LineFromY(int y) { |
| 436 int current_height = 0; | 434 int current_height = 0; |
| 437 | 435 |
| 438 for (size_t i = 0; i < identifiers().size(); ++i) { | 436 for (size_t i = 0; i < identifiers().size(); ++i) { |
| 439 current_height += GetRowHeightFromId(identifiers()[i]); | 437 current_height += GetRowHeightFromId(identifiers()[i]); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 int AutofillPopupControllerImpl::GetDesiredPopupHeight() const { | 519 int AutofillPopupControllerImpl::GetDesiredPopupHeight() const { |
| 522 int popup_height = 0; | 520 int popup_height = 0; |
| 523 | 521 |
| 524 for (size_t i = 0; i < identifiers().size(); ++i) { | 522 for (size_t i = 0; i < identifiers().size(); ++i) { |
| 525 popup_height += GetRowHeightFromId(identifiers()[i]); | 523 popup_height += GetRowHeightFromId(identifiers()[i]); |
| 526 } | 524 } |
| 527 | 525 |
| 528 return popup_height; | 526 return popup_height; |
| 529 } | 527 } |
| 530 | 528 |
| 529 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetWeakPtr() { |
| 530 return weak_ptr_factory_.GetWeakPtr(); |
| 531 } |
| 532 |
| 531 int AutofillPopupControllerImpl::RowWidthWithoutText(int row) const { | 533 int AutofillPopupControllerImpl::RowWidthWithoutText(int row) const { |
| 532 int row_size = kEndPadding + kNamePadding; | 534 int row_size = kEndPadding + kNamePadding; |
| 533 | 535 |
| 534 // Add the Autofill icon size, if required. | 536 // Add the Autofill icon size, if required. |
| 535 if (!icons_[row].empty()) | 537 if (!icons_[row].empty()) |
| 536 row_size += kAutofillIconWidth + kIconPadding; | 538 row_size += kAutofillIconWidth + kIconPadding; |
| 537 | 539 |
| 538 // Add the delete icon size, if required. | 540 // Add the delete icon size, if required. |
| 539 if (CanDelete(row)) | 541 if (CanDelete(row)) |
| 540 row_size += kDeleteIconWidth + kIconPadding; | 542 row_size += kDeleteIconWidth + kIconPadding; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 if (bottom_available >= popup_required_height || | 645 if (bottom_available >= popup_required_height || |
| 644 bottom_available >= top_available) { | 646 bottom_available >= top_available) { |
| 645 // The popup can appear below the field. | 647 // The popup can appear below the field. |
| 646 return std::make_pair(bottom_growth_start, popup_required_height); | 648 return std::make_pair(bottom_growth_start, popup_required_height); |
| 647 } else { | 649 } else { |
| 648 // The popup must appear above the field. | 650 // The popup must appear above the field. |
| 649 return std::make_pair(top_growth_end - popup_required_height, | 651 return std::make_pair(top_growth_end - popup_required_height, |
| 650 popup_required_height); | 652 popup_required_height); |
| 651 } | 653 } |
| 652 } | 654 } |
| OLD | NEW |