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

Side by Side Diff: chrome/browser/ui/autofill/autofill_popup_controller_impl.cc

Issue 2727233003: Uses child views in Autofill Popup so we can trigger (Closed)
Patch Set: Combines 2 calls to InvalidateRow to 1 OnSelectedRowChanged call. Created 3 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
OLDNEW
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/command_line.h" 10 #include "base/command_line.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "build/build_config.h" 14 #include "build/build_config.h"
15 #include "chrome/browser/ui/autofill/autofill_popup_view.h" 15 #include "chrome/browser/ui/autofill/autofill_popup_view.h"
16 #include "components/autofill/core/browser/autofill_popup_delegate.h" 16 #include "components/autofill/core/browser/autofill_popup_delegate.h"
17 #include "components/autofill/core/browser/popup_item_ids.h" 17 #include "components/autofill/core/browser/popup_item_ids.h"
18 #include "components/autofill/core/browser/suggestion.h" 18 #include "components/autofill/core/browser/suggestion.h"
19 #include "content/public/browser/native_web_keyboard_event.h" 19 #include "content/public/browser/native_web_keyboard_event.h"
20 #include "ui/events/event.h" 20 #include "ui/events/event.h"
21 #include "ui/gfx/canvas.h" 21 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/text_elider.h" 22 #include "ui/gfx/text_elider.h"
23 #include "ui/gfx/text_utils.h" 23 #include "ui/gfx/text_utils.h"
24 24
25 using base::WeakPtr; 25 using base::WeakPtr;
26 26
27 namespace autofill { 27 namespace autofill {
28 namespace { 28 namespace {
29 29
30 // Used to indicate that no line is currently selected by the user. 30 const auto& kNoSelection = AutofillPopupView::kNoSelection;
groby-ooo-7-16 2017/03/20 20:42:55 Why define a new constant here? (And if we must, p
csashi 2017/03/20 21:41:51 I removed this a few patches ago. Can you please c
groby-ooo-7-16 2017/03/20 22:53:10 Acknowledged.
31 const int kNoSelection = -1;
32 31
33 } // namespace 32 } // namespace
34 33
35 // static 34 // static
36 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetOrCreate( 35 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetOrCreate(
37 WeakPtr<AutofillPopupControllerImpl> previous, 36 WeakPtr<AutofillPopupControllerImpl> previous,
38 WeakPtr<AutofillPopupDelegate> delegate, 37 WeakPtr<AutofillPopupDelegate> delegate,
39 content::WebContents* web_contents, 38 content::WebContents* web_contents,
40 gfx::NativeView container_view, 39 gfx::NativeView container_view,
41 const gfx::RectF& element_bounds, 40 const gfx::RectF& element_bounds,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 // Elide the name and label strings so that the popup fits in the available 106 // Elide the name and label strings so that the popup fits in the available
108 // space. 107 // space.
109 for (size_t i = 0; i < suggestions_.size(); ++i) { 108 for (size_t i = 0; i < suggestions_.size(); ++i) {
110 bool has_label = !suggestions_[i].label.empty(); 109 bool has_label = !suggestions_[i].label.empty();
111 ElideValueAndLabelForRow( 110 ElideValueAndLabelForRow(
112 i, layout_model_.GetAvailableWidthForRow(i, has_label)); 111 i, layout_model_.GetAvailableWidthForRow(i, has_label));
113 } 112 }
114 #endif 113 #endif
115 114
116 if (just_created) { 115 if (just_created) {
117 ShowView(); 116 view_->Show();
118 } else { 117 } else {
119 UpdateBoundsAndRedrawPopup(); 118 OnSuggestionsChanged();
120 } 119 }
121 120
122 controller_common_->RegisterKeyPressCallback(); 121 controller_common_->RegisterKeyPressCallback();
123 delegate_->OnPopupShown(); 122 delegate_->OnPopupShown();
124 123
125 DCHECK_EQ(suggestions_.size(), elided_values_.size()); 124 DCHECK_EQ(suggestions_.size(), elided_values_.size());
126 DCHECK_EQ(suggestions_.size(), elided_labels_.size()); 125 DCHECK_EQ(suggestions_.size(), elided_labels_.size());
127 } 126 }
128 127
129 void AutofillPopupControllerImpl::UpdateDataListValues( 128 void AutofillPopupControllerImpl::UpdateDataListValues(
(...skipping 16 matching lines...) Expand all
146 if (values.empty()) { 145 if (values.empty()) {
147 if (!suggestions_.empty() && 146 if (!suggestions_.empty() &&
148 suggestions_[0].frontend_id == POPUP_ITEM_ID_SEPARATOR) { 147 suggestions_[0].frontend_id == POPUP_ITEM_ID_SEPARATOR) {
149 suggestions_.erase(suggestions_.begin()); 148 suggestions_.erase(suggestions_.begin());
150 elided_values_.erase(elided_values_.begin()); 149 elided_values_.erase(elided_values_.begin());
151 elided_labels_.erase(elided_labels_.begin()); 150 elided_labels_.erase(elided_labels_.begin());
152 } 151 }
153 152
154 // The popup contents have changed, so either update the bounds or hide it. 153 // The popup contents have changed, so either update the bounds or hide it.
155 if (HasSuggestions()) 154 if (HasSuggestions())
156 UpdateBoundsAndRedrawPopup(); 155 OnSuggestionsChanged();
157 else 156 else
158 Hide(); 157 Hide();
159 158
160 return; 159 return;
161 } 160 }
162 161
163 // Add a separator if there are any other values. 162 // Add a separator if there are any other values.
164 if (!suggestions_.empty() && 163 if (!suggestions_.empty() &&
165 suggestions_[0].frontend_id != POPUP_ITEM_ID_SEPARATOR) { 164 suggestions_[0].frontend_id != POPUP_ITEM_ID_SEPARATOR) {
166 suggestions_.insert(suggestions_.begin(), autofill::Suggestion()); 165 suggestions_.insert(suggestions_.begin(), autofill::Suggestion());
(...skipping 11 matching lines...) Expand all
178 for (size_t i = 0; i < values.size(); i++) { 177 for (size_t i = 0; i < values.size(); i++) {
179 suggestions_[i].value = values[i]; 178 suggestions_[i].value = values[i];
180 suggestions_[i].label = labels[i]; 179 suggestions_[i].label = labels[i];
181 suggestions_[i].frontend_id = POPUP_ITEM_ID_DATALIST_ENTRY; 180 suggestions_[i].frontend_id = POPUP_ITEM_ID_DATALIST_ENTRY;
182 181
183 // TODO(brettw) it looks like these should be elided. 182 // TODO(brettw) it looks like these should be elided.
184 elided_values_[i] = values[i]; 183 elided_values_[i] = values[i];
185 elided_labels_[i] = labels[i]; 184 elided_labels_[i] = labels[i];
186 } 185 }
187 186
188 UpdateBoundsAndRedrawPopup(); 187 OnSuggestionsChanged();
189 DCHECK_EQ(suggestions_.size(), elided_values_.size()); 188 DCHECK_EQ(suggestions_.size(), elided_values_.size());
190 DCHECK_EQ(suggestions_.size(), elided_labels_.size()); 189 DCHECK_EQ(suggestions_.size(), elided_labels_.size());
191 } 190 }
192 191
193 void AutofillPopupControllerImpl::Hide() { 192 void AutofillPopupControllerImpl::Hide() {
194 controller_common_->RemoveKeyPressCallback(); 193 controller_common_->RemoveKeyPressCallback();
195 if (delegate_) 194 if (delegate_)
196 delegate_->OnPopupHidden(); 195 delegate_->OnPopupHidden();
197 196
198 if (view_) 197 if (view_)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 // location. 237 // location.
239 AcceptSelectedLine(); 238 AcceptSelectedLine();
240 return false; 239 return false;
241 case ui::VKEY_RETURN: 240 case ui::VKEY_RETURN:
242 return AcceptSelectedLine(); 241 return AcceptSelectedLine();
243 default: 242 default:
244 return false; 243 return false;
245 } 244 }
246 } 245 }
247 246
248 void AutofillPopupControllerImpl::UpdateBoundsAndRedrawPopup() { 247 void AutofillPopupControllerImpl::OnSuggestionsChanged() {
249 #if !defined(OS_ANDROID) 248 #if !defined(OS_ANDROID)
250 // TODO(csharp): Since UpdatePopupBounds can change the position of the popup, 249 // TODO(csharp): Since UpdatePopupBounds can change the position of the popup,
251 // the popup could end up jumping from above the element to below it. 250 // the popup could end up jumping from above the element to below it.
252 // It is unclear if it is better to keep the popup where it was, or if it 251 // It is unclear if it is better to keep the popup where it was, or if it
253 // should try and move to its desired position. 252 // should try and move to its desired position.
254 layout_model_.UpdatePopupBounds(); 253 layout_model_.UpdatePopupBounds();
255 #endif 254 #endif
256 255
257 // Platform-specific draw call. 256 // Platform-specific draw call.
258 view_->UpdateBoundsAndRedrawPopup(); 257 view_->OnSuggestionsChanged();
259 } 258 }
260 259
261 void AutofillPopupControllerImpl::SetSelectionAtPoint(const gfx::Point& point) { 260 void AutofillPopupControllerImpl::SetSelectionAtPoint(const gfx::Point& point) {
262 SetSelectedLine(layout_model_.LineFromY(point.y())); 261 SetSelectedLine(layout_model_.LineFromY(point.y()));
263 } 262 }
264 263
265 bool AutofillPopupControllerImpl::AcceptSelectedLine() { 264 bool AutofillPopupControllerImpl::AcceptSelectedLine() {
266 if (selected_line_ == kNoSelection) 265 if (selected_line_ == kNoSelection)
267 return false; 266 return false;
268 267
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 358
360 // Remove the deleted element. 359 // Remove the deleted element.
361 suggestions_.erase(suggestions_.begin() + list_index); 360 suggestions_.erase(suggestions_.begin() + list_index);
362 elided_values_.erase(elided_values_.begin() + list_index); 361 elided_values_.erase(elided_values_.begin() + list_index);
363 elided_labels_.erase(elided_labels_.begin() + list_index); 362 elided_labels_.erase(elided_labels_.begin() + list_index);
364 363
365 SetSelectedLine(kNoSelection); 364 SetSelectedLine(kNoSelection);
366 365
367 if (HasSuggestions()) { 366 if (HasSuggestions()) {
368 delegate_->ClearPreviewedForm(); 367 delegate_->ClearPreviewedForm();
369 UpdateBoundsAndRedrawPopup(); 368 OnSuggestionsChanged();
370 } else { 369 } else {
371 Hide(); 370 Hide();
372 } 371 }
373 372
374 return true; 373 return true;
375 } 374 }
376 375
377 ui::NativeTheme::ColorId 376 ui::NativeTheme::ColorId
378 AutofillPopupControllerImpl::GetBackgroundColorIDForRow(int index) const { 377 AutofillPopupControllerImpl::GetBackgroundColorIDForRow(int index) const {
379 return index == selected_line_ ? 378 return index == selected_line_ ?
380 ui::NativeTheme::kColorId_ResultsTableHoveredBackground : 379 ui::NativeTheme::kColorId_ResultsTableHoveredBackground :
381 ui::NativeTheme::kColorId_ResultsTableNormalBackground; 380 ui::NativeTheme::kColorId_ResultsTableNormalBackground;
382 } 381 }
383 382
384 int AutofillPopupControllerImpl::selected_line() const { 383 int AutofillPopupControllerImpl::selected_line() const {
385 return selected_line_; 384 return selected_line_;
386 } 385 }
387 386
388 const AutofillPopupLayoutModel& AutofillPopupControllerImpl::layout_model() 387 const AutofillPopupLayoutModel& AutofillPopupControllerImpl::layout_model()
389 const { 388 const {
390 return layout_model_; 389 return layout_model_;
391 } 390 }
392 391
393 void AutofillPopupControllerImpl::SetSelectedLine(int selected_line) { 392 void AutofillPopupControllerImpl::SetSelectedLine(int selected_line) {
394 if (selected_line_ == selected_line) 393 if (selected_line_ == selected_line)
395 return; 394 return;
396 395
397 if (selected_line_ != kNoSelection &&
398 static_cast<size_t>(selected_line_) < suggestions_.size())
399 InvalidateRow(selected_line_);
400
401 if (selected_line != kNoSelection) { 396 if (selected_line != kNoSelection) {
402 InvalidateRow(selected_line); 397 DCHECK_GE(selected_line, 0);
403 398 DCHECK_LT(static_cast<size_t>(selected_line), suggestions_.size());
404 if (!CanAccept(suggestions_[selected_line].frontend_id)) 399 if (!CanAccept(suggestions_[selected_line].frontend_id))
405 selected_line = kNoSelection; 400 selected_line = kNoSelection;
406 } 401 }
407 402
403 view_->OnSelectedRowChanged(selected_line_, selected_line);
404
408 selected_line_ = selected_line; 405 selected_line_ = selected_line;
409 406
410 if (selected_line_ != kNoSelection) { 407 if (selected_line_ != kNoSelection) {
411 delegate_->DidSelectSuggestion(suggestions_[selected_line_].value, 408 delegate_->DidSelectSuggestion(suggestions_[selected_line_].value,
412 suggestions_[selected_line_].frontend_id); 409 suggestions_[selected_line_].frontend_id);
413 } else { 410 } else {
414 delegate_->ClearPreviewedForm(); 411 delegate_->ClearPreviewedForm();
415 } 412 }
416 } 413 }
417 414
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 const std::vector<autofill::Suggestion>& suggestions) { 472 const std::vector<autofill::Suggestion>& suggestions) {
476 suggestions_ = suggestions; 473 suggestions_ = suggestions;
477 elided_values_.resize(suggestions.size()); 474 elided_values_.resize(suggestions.size());
478 elided_labels_.resize(suggestions.size()); 475 elided_labels_.resize(suggestions.size());
479 for (size_t i = 0; i < suggestions.size(); i++) { 476 for (size_t i = 0; i < suggestions.size(); i++) {
480 elided_values_[i] = suggestions[i].value; 477 elided_values_[i] = suggestions[i].value;
481 elided_labels_[i] = suggestions[i].label; 478 elided_labels_[i] = suggestions[i].label;
482 } 479 }
483 } 480 }
484 481
485 void AutofillPopupControllerImpl::ShowView() {
486 view_->Show();
487 }
488
489 void AutofillPopupControllerImpl::InvalidateRow(size_t row) {
490 DCHECK(0 <= row);
491 DCHECK(row < suggestions_.size());
492 view_->InvalidateRow(row);
493 }
494
495 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetWeakPtr() { 482 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetWeakPtr() {
496 return weak_ptr_factory_.GetWeakPtr(); 483 return weak_ptr_factory_.GetWeakPtr();
497 } 484 }
498 485
499 #if !defined(OS_ANDROID) 486 #if !defined(OS_ANDROID)
500 void AutofillPopupControllerImpl::ElideValueAndLabelForRow( 487 void AutofillPopupControllerImpl::ElideValueAndLabelForRow(
501 size_t row, 488 size_t row,
502 int available_width) { 489 int available_width) {
503 int value_width = gfx::GetStringWidth( 490 int value_width = gfx::GetStringWidth(
504 suggestions_[row].value, layout_model_.GetValueFontListForRow(row)); 491 suggestions_[row].value, layout_model_.GetValueFontListForRow(row));
(...skipping 23 matching lines...) Expand all
528 // Don't clear view_, because otherwise the popup will have to get regenerated 515 // Don't clear view_, because otherwise the popup will have to get regenerated
529 // and this will cause flickering. 516 // and this will cause flickering.
530 suggestions_.clear(); 517 suggestions_.clear();
531 elided_values_.clear(); 518 elided_values_.clear();
532 elided_labels_.clear(); 519 elided_labels_.clear();
533 520
534 selected_line_ = kNoSelection; 521 selected_line_ = kNoSelection;
535 } 522 }
536 523
537 } // namespace autofill 524 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698