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

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

Issue 11817051: Elide text in the new Autofill UI (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 11 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 "base/logging.h" 7 #include "base/logging.h"
8 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/ui/autofill/autofill_popup_delegate.h" 9 #include "chrome/browser/ui/autofill/autofill_popup_delegate.h"
10 #include "chrome/browser/ui/autofill/autofill_popup_view.h" 10 #include "chrome/browser/ui/autofill/autofill_popup_view.h"
11 #include "content/public/browser/native_web_keyboard_event.h" 11 #include "content/public/browser/native_web_keyboard_event.h"
12 #include "grit/webkit_resources.h" 12 #include "grit/webkit_resources.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h" 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h"
14 #include "ui/base/events/event.h" 14 #include "ui/base/events/event.h"
15 #include "ui/base/text/text_elider.h"
16 #include "ui/gfx/display.h"
17 #include "ui/gfx/screen.h"
18 #include "ui/gfx/vector2d.h"
15 19
16 using WebKit::WebAutofillClient; 20 using WebKit::WebAutofillClient;
17 21
18 namespace { 22 namespace {
19 23
20 // Used to indicate that no line is currently selected by the user. 24 // Used to indicate that no line is currently selected by the user.
21 const int kNoSelection = -1; 25 const int kNoSelection = -1;
22 26
23 // Size difference between name and subtext in pixels. 27 // Size difference between name and subtext in pixels.
24 const int kLabelFontSizeDelta = -2; 28 const int kLabelFontSizeDelta = -2;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 const std::vector<string16>& icons, 115 const std::vector<string16>& icons,
112 const std::vector<int>& identifiers) { 116 const std::vector<int>& identifiers) {
113 names_ = names; 117 names_ = names;
114 subtexts_ = subtexts; 118 subtexts_ = subtexts;
115 icons_ = icons; 119 icons_ = icons;
116 identifiers_ = identifiers; 120 identifiers_ = identifiers;
117 121
118 #if !defined(OS_ANDROID) 122 #if !defined(OS_ANDROID)
119 // Android displays the long text with ellipsis using the view attributes. 123 // Android displays the long text with ellipsis using the view attributes.
120 124
121 // TODO(csharp): Fix crbug.com/156163 and use better logic when clipping. 125 int popup_width = CalculateAndSetPopupWidth();
126
127 // Elide the name and subtext strings so that the popup fits in the available
128 // space.
122 for (size_t i = 0; i < names_.size(); ++i) { 129 for (size_t i = 0; i < names_.size(); ++i) {
123 if (names_[i].length() > 15) 130 int total_text_length = name_font().GetStringWidth(names[i]) +
124 names_[i].erase(15); 131 subtext_font().GetStringWidth(subtexts_[i]);
125 if (subtexts[i].length() > 15) 132 // The line can have no strings if it represents a UI element, such as
126 subtexts_[i].erase(15); 133 // a separator line.
134 if (total_text_length == 0)
135 continue;
136
137 int available_width = popup_width - RowWidthWithoutText(i);
138
139 // Each field recieves space in proportion to its length.
140 int name_size = available_width *
141 name_font().GetStringWidth(names_[i]) / total_text_length;
Ilya Sherman 2013/01/11 23:05:35 nit: Might be worth caching the result of the GetS
csharp 2013/01/14 20:32:33 Done.
142 names_[i] = ui::ElideText(names_[i],
143 name_font(),
144 name_size,
145 ui::ELIDE_AT_END);
146
147 int subtext_size = available_width *
148 subtext_font().GetStringWidth(subtexts[i]) / total_text_length;
149 subtexts_[i] = ui::ElideText(subtexts_[i],
150 subtext_font(),
151 subtext_size,
152 ui::ELIDE_AT_END);
127 } 153 }
128 #endif 154 #endif
129 155
130 if (!view_) { 156 if (!view_) {
131 view_ = AutofillPopupView::Create(this); 157 view_ = AutofillPopupView::Create(this);
132 ShowView(); 158 ShowView();
133 } else { 159 } else {
134 UpdateBoundsAndRedrawPopup(); 160 UpdateBoundsAndRedrawPopup();
135 } 161 }
136 } 162 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 } 217 }
192 218
193 bool AutofillPopupControllerImpl::CanDelete(size_t index) { 219 bool AutofillPopupControllerImpl::CanDelete(size_t index) {
194 int id = identifiers_[index]; 220 int id = identifiers_[index];
195 return id > 0 || 221 return id > 0 ||
196 id == WebAutofillClient::MenuItemIDAutocompleteEntry || 222 id == WebAutofillClient::MenuItemIDAutocompleteEntry ||
197 id == WebAutofillClient::MenuItemIDPasswordEntry; 223 id == WebAutofillClient::MenuItemIDPasswordEntry;
198 } 224 }
199 225
200 #if !defined(OS_ANDROID) 226 #if !defined(OS_ANDROID)
201 int AutofillPopupControllerImpl::GetPopupRequiredWidth() { 227 int AutofillPopupControllerImpl::GetPopupRequiredWidth() {
Ilya Sherman 2013/01/11 23:05:35 Rather than exposing this method to the view, IMO
csharp 2013/01/14 20:32:33 Done.
202 if (name_font_.platform_font() == NULL || 228 if (name_font_.platform_font() == NULL ||
203 subtext_font_.platform_font() == NULL) { 229 subtext_font_.platform_font() == NULL) {
204 // We can't calculate the size of the popup if the fonts 230 // We can't calculate the size of the popup if the fonts
205 // aren't present. 231 // aren't present.
206 return 0; 232 return 0;
207 } 233 }
208 234
209 int popup_width = element_bounds().width(); 235 int popup_width = element_bounds().width();
210 DCHECK_EQ(names().size(), subtexts().size()); 236 DCHECK_EQ(names().size(), subtexts().size());
211 for (size_t i = 0; i < names().size(); ++i) { 237 for (size_t i = 0; i < names().size(); ++i) {
212 int row_size = kEndPadding + 238 int row_size = name_font_.GetStringWidth(names()[i]) +
213 name_font_.GetStringWidth(names()[i]) + 239 subtext_font_.GetStringWidth(subtexts()[i]) +
214 kNamePadding + 240 RowWidthWithoutText(i);
215 subtext_font_.GetStringWidth(subtexts()[i]);
216
217 // Add the Autofill icon size, if required.
218 if (!icons()[i].empty())
219 row_size += kAutofillIconWidth + kIconPadding;
220
221 // Add delete icon, if required.
222 if (CanDelete(i))
223 row_size += kDeleteIconWidth + kIconPadding;
224
225 // Add the padding at the end
226 row_size += kEndPadding;
227 241
228 popup_width = std::max(popup_width, row_size); 242 popup_width = std::max(popup_width, row_size);
229 } 243 }
230 244
231 return popup_width; 245 return popup_width;
232 } 246 }
233 247
234 int AutofillPopupControllerImpl::GetPopupRequiredHeight() { 248 int AutofillPopupControllerImpl::GetPopupRequiredHeight() {
235 int popup_height = 0; 249 int popup_height = 0;
236 250
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 identifiers_[0] == WebAutofillClient::MenuItemIDDataListEntry); 511 identifiers_[0] == WebAutofillClient::MenuItemIDDataListEntry);
498 } 512 }
499 513
500 void AutofillPopupControllerImpl::ShowView() { 514 void AutofillPopupControllerImpl::ShowView() {
501 view_->Show(); 515 view_->Show();
502 } 516 }
503 517
504 void AutofillPopupControllerImpl::InvalidateRow(size_t row) { 518 void AutofillPopupControllerImpl::InvalidateRow(size_t row) {
505 view_->InvalidateRow(row); 519 view_->InvalidateRow(row);
506 } 520 }
521
522 int AutofillPopupControllerImpl::RowWidthWithoutText(int row) {
523 int row_size = kEndPadding + kNamePadding;
524
525 // Add the Autofill icon size, if required.
526 if (!icons_[row].empty())
527 row_size += kAutofillIconWidth + kIconPadding;
528
529 // Add the delete icon size, if required.
530 if (CanDelete(row))
531 row_size += kDeleteIconWidth + kIconPadding;
532
533 // Add the padding at the end
534 row_size += kEndPadding;
535
536 return row_size;
537 }
538
539 int AutofillPopupControllerImpl::CalculateAndSetPopupWidth() {
540 int popup_required_width = GetPopupRequiredWidth();
541 gfx::Point right_corner_of_popup = element_bounds().origin() +
542 gfx::Vector2d(popup_required_width, 0);
543
544 gfx::Screen* screen =
545 gfx::Screen::GetScreenFor(container_view());
546 gfx::Display left_display = screen->GetDisplayNearestPoint(
547 element_bounds().origin());
Ilya Sherman 2013/01/11 23:05:35 Hmm, shouldn't this be the display that's at the l
csharp 2013/01/14 20:32:33 Yup, fixed.
548 gfx::Display right_display = screen->GetDisplayNearestPoint(
549 right_corner_of_popup);
550
551 int leftmost_display_x = left_display.bounds().x() *
552 left_display.device_scale_factor();
553 int rightmost_display_x = right_display.GetSizeInPixel().width() +
554 right_display.bounds().x() * right_display.device_scale_factor();
555
556 // Calculate the leftmost and rightmost values the popup can have without
557 // going off the screen.
558 int popup_left_cutoff = std::max(element_bounds().origin().x(),
559 leftmost_display_x);
Ilya Sherman 2013/01/11 23:05:35 nit: indentation
csharp 2013/01/14 20:32:33 Done.
560 int popup_right_cutoff = std::min(element_bounds().top_right().x(),
561 rightmost_display_x);
Ilya Sherman 2013/01/11 23:05:35 nit: indentation
csharp 2013/01/14 20:32:33 Done.
562
563 int right_available = rightmost_display_x - popup_left_cutoff;
564 int left_available = popup_right_cutoff - leftmost_display_x;
565
566 int popup_width = std::min(popup_required_width,
567 std::max(right_available, left_available));
Ilya Sherman 2013/01/11 23:05:35 nit: #include <algorithm> for std::min and ::max.
csharp 2013/01/14 20:32:33 Done.
568 // If there is enough space for the popup on the right, show it there,
569 // otherwise choose the larger size.
570 if (right_available >= popup_width || right_available >= left_available) {
571 popup_bounds_.set_x(popup_left_cutoff);
572 } else {
573 popup_bounds_.set_x(popup_right_cutoff - popup_width);
574 }
Ilya Sherman 2013/01/11 23:05:35 nit: No need for curlies
csharp 2013/01/14 20:32:33 Done.
575
576 return popup_width;
577 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698