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

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

Issue 12188020: Adding the page and DPI scale adjustment for Autofill Popups. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed Ted's nits Created 7 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 | Annotate | Revision Log
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/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/rect_conversions.h"
20 #include "ui/gfx/screen.h" 21 #include "ui/gfx/screen.h"
21 #include "ui/gfx/vector2d.h" 22 #include "ui/gfx/vector2d.h"
22 23
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
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 AutofillPopupControllerImpl* AutofillPopupControllerImpl::GetOrCreate(
74 AutofillPopupControllerImpl* previous, 75 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::RectF& 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 return new AutofillPopupControllerImpl(
90 delegate, container_view, element_bounds); 91 delegate, container_view, element_bounds);
91 } 92 }
92 93
93 AutofillPopupControllerImpl::AutofillPopupControllerImpl( 94 AutofillPopupControllerImpl::AutofillPopupControllerImpl(
94 AutofillPopupDelegate* delegate, 95 AutofillPopupDelegate* delegate,
95 gfx::NativeView container_view, 96 gfx::NativeView container_view,
96 const gfx::Rect& element_bounds) 97 const gfx::RectF& element_bounds)
97 : view_(NULL), 98 : view_(NULL),
98 delegate_(delegate), 99 delegate_(delegate),
99 container_view_(container_view), 100 container_view_(container_view),
100 element_bounds_(element_bounds), 101 element_bounds_(element_bounds),
101 selected_line_(kNoSelection), 102 selected_line_(kNoSelection),
102 delete_icon_hovered_(false), 103 delete_icon_hovered_(false),
103 is_hiding_(false), 104 is_hiding_(false),
104 inform_delegate_of_destruction_(true) { 105 inform_delegate_of_destruction_(true) {
105 #if !defined(OS_ANDROID) 106 #if !defined(OS_ANDROID)
106 subtext_font_ = name_font_.DeriveFont(kLabelFontSizeDelta); 107 subtext_font_ = name_font_.DeriveFont(kLabelFontSizeDelta);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 } 281 }
281 282
282 const gfx::Rect& AutofillPopupControllerImpl::popup_bounds() const { 283 const gfx::Rect& AutofillPopupControllerImpl::popup_bounds() const {
283 return popup_bounds_; 284 return popup_bounds_;
284 } 285 }
285 286
286 gfx::NativeView AutofillPopupControllerImpl::container_view() const { 287 gfx::NativeView AutofillPopupControllerImpl::container_view() const {
287 return container_view_; 288 return container_view_;
288 } 289 }
289 290
290 const gfx::Rect& AutofillPopupControllerImpl::element_bounds() const { 291 const gfx::RectF& AutofillPopupControllerImpl::element_bounds() const {
291 return element_bounds_; 292 return element_bounds_;
292 } 293 }
293 294
294 const std::vector<string16>& AutofillPopupControllerImpl::names() const { 295 const std::vector<string16>& AutofillPopupControllerImpl::names() const {
295 return names_; 296 return names_;
296 } 297 }
297 298
298 const std::vector<string16>& AutofillPopupControllerImpl::subtexts() const { 299 const std::vector<string16>& AutofillPopupControllerImpl::subtexts() const {
299 return subtexts_; 300 return subtexts_;
300 } 301 }
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 } 499 }
499 500
500 #if !defined(OS_ANDROID) 501 #if !defined(OS_ANDROID)
501 int AutofillPopupControllerImpl::GetDesiredPopupWidth() const { 502 int AutofillPopupControllerImpl::GetDesiredPopupWidth() const {
502 if (!name_font_.platform_font() || !subtext_font_.platform_font()) { 503 if (!name_font_.platform_font() || !subtext_font_.platform_font()) {
503 // We can't calculate the size of the popup if the fonts 504 // We can't calculate the size of the popup if the fonts
504 // aren't present. 505 // aren't present.
505 return 0; 506 return 0;
506 } 507 }
507 508
508 int popup_width = element_bounds().width(); 509 int popup_width = RoundedElementBounds().width();
509 DCHECK_EQ(names().size(), subtexts().size()); 510 DCHECK_EQ(names().size(), subtexts().size());
510 for (size_t i = 0; i < names().size(); ++i) { 511 for (size_t i = 0; i < names().size(); ++i) {
511 int row_size = name_font_.GetStringWidth(names()[i]) + 512 int row_size = name_font_.GetStringWidth(names()[i]) +
512 subtext_font_.GetStringWidth(subtexts()[i]) + 513 subtext_font_.GetStringWidth(subtexts()[i]) +
513 RowWidthWithoutText(i); 514 RowWidthWithoutText(i);
514 515
515 popup_width = std::max(popup_width, row_size); 516 popup_width = std::max(popup_width, row_size);
516 } 517 }
517 518
518 return popup_width; 519 return popup_width;
(...skipping 25 matching lines...) Expand all
544 545
545 return row_size; 546 return row_size;
546 } 547 }
547 548
548 void AutofillPopupControllerImpl::UpdatePopupBounds() { 549 void AutofillPopupControllerImpl::UpdatePopupBounds() {
549 int popup_required_width = GetDesiredPopupWidth(); 550 int popup_required_width = GetDesiredPopupWidth();
550 int popup_height = GetDesiredPopupHeight(); 551 int popup_height = GetDesiredPopupHeight();
551 // This is the top left point of the popup if the popup is above the element 552 // This is the top left point of the popup if the popup is above the element
552 // and grows to the left (since that is the highest and furthest left the 553 // and grows to the left (since that is the highest and furthest left the
553 // popup go could). 554 // popup go could).
554 gfx::Point top_left_corner_of_popup = element_bounds().origin() + 555 gfx::Point top_left_corner_of_popup = RoundedElementBounds().origin() +
555 gfx::Vector2d(element_bounds().width() - popup_required_width, 556 gfx::Vector2d(RoundedElementBounds().width() - popup_required_width,
556 -popup_height); 557 -popup_height);
557 558
558 // This is the bottom right point of the popup if the popup is below the 559 // This is the bottom right point of the popup if the popup is below the
559 // element and grows to the right (since the is the lowest and furthest right 560 // element and grows to the right (since the is the lowest and furthest right
560 // the popup could go). 561 // the popup could go).
561 gfx::Point bottom_right_corner_of_popup = element_bounds().origin() + 562 gfx::Point bottom_right_corner_of_popup = RoundedElementBounds().origin() +
562 gfx::Vector2d(popup_required_width, 563 gfx::Vector2d(popup_required_width,
563 element_bounds().height() + popup_height); 564 RoundedElementBounds().height() + popup_height);
564 565
565 gfx::Display top_left_display = GetDisplayNearestPoint( 566 gfx::Display top_left_display = GetDisplayNearestPoint(
566 top_left_corner_of_popup); 567 top_left_corner_of_popup);
567 gfx::Display bottom_right_display = GetDisplayNearestPoint( 568 gfx::Display bottom_right_display = GetDisplayNearestPoint(
568 bottom_right_corner_of_popup); 569 bottom_right_corner_of_popup);
569 570
570 std::pair<int, int> popup_x_and_width = CalculatePopupXAndWidth( 571 std::pair<int, int> popup_x_and_width = CalculatePopupXAndWidth(
571 top_left_display, bottom_right_display, popup_required_width); 572 top_left_display, bottom_right_display, popup_required_width);
572 std::pair<int, int> popup_y_and_height = CalculatePopupYAndHeight( 573 std::pair<int, int> popup_y_and_height = CalculatePopupYAndHeight(
573 top_left_display, bottom_right_display, popup_height); 574 top_left_display, bottom_right_display, popup_height);
574 575
575 popup_bounds_ = gfx::Rect(popup_x_and_width.first, 576 popup_bounds_ = gfx::Rect(popup_x_and_width.first,
576 popup_y_and_height.first, 577 popup_y_and_height.first,
577 popup_x_and_width.second, 578 popup_x_and_width.second,
578 popup_y_and_height.second); 579 popup_y_and_height.second);
579 } 580 }
580 #endif // !defined(OS_ANDROID) 581 #endif // !defined(OS_ANDROID)
581 582
583 const gfx::Rect AutofillPopupControllerImpl::RoundedElementBounds() const {
584 return gfx::ToNearestRect(element_bounds_);
585 }
586
582 gfx::Display AutofillPopupControllerImpl::GetDisplayNearestPoint( 587 gfx::Display AutofillPopupControllerImpl::GetDisplayNearestPoint(
583 const gfx::Point& point) const { 588 const gfx::Point& point) const {
584 return gfx::Screen::GetScreenFor(container_view())->GetDisplayNearestPoint( 589 return gfx::Screen::GetScreenFor(container_view())->GetDisplayNearestPoint(
585 point); 590 point);
586 } 591 }
587 592
588 std::pair<int, int> AutofillPopupControllerImpl::CalculatePopupXAndWidth( 593 std::pair<int, int> AutofillPopupControllerImpl::CalculatePopupXAndWidth(
589 const gfx::Display& left_display, 594 const gfx::Display& left_display,
590 const gfx::Display& right_display, 595 const gfx::Display& right_display,
591 int popup_required_width) const { 596 int popup_required_width) const {
592 int leftmost_display_x = left_display.bounds().x() * 597 int leftmost_display_x = left_display.bounds().x() *
593 left_display.device_scale_factor(); 598 left_display.device_scale_factor();
594 int rightmost_display_x = right_display.GetSizeInPixel().width() + 599 int rightmost_display_x = right_display.GetSizeInPixel().width() +
595 right_display.bounds().x() * right_display.device_scale_factor(); 600 right_display.bounds().x() * right_display.device_scale_factor();
596 601
597 // Calculate the start coordinates for the popup if it is growing right or 602 // Calculate the start coordinates for the popup if it is growing right or
598 // the end position if it is growing to the left, capped to screen space. 603 // the end position if it is growing to the left, capped to screen space.
599 int right_growth_start = std::max(leftmost_display_x, 604 int right_growth_start = std::max(leftmost_display_x,
600 std::min(rightmost_display_x, 605 std::min(rightmost_display_x,
601 element_bounds().x())); 606 RoundedElementBounds().x()));
602 int left_growth_end = std::max(leftmost_display_x, 607 int left_growth_end = std::max(leftmost_display_x,
603 std::min(rightmost_display_x, 608 std::min(rightmost_display_x,
604 element_bounds().right())); 609 RoundedElementBounds().right()));
605 610
606 int right_available = rightmost_display_x - right_growth_start; 611 int right_available = rightmost_display_x - right_growth_start;
607 int left_available = left_growth_end - leftmost_display_x; 612 int left_available = left_growth_end - leftmost_display_x;
608 613
609 int popup_width = std::min(popup_required_width, 614 int popup_width = std::min(popup_required_width,
610 std::max(right_available, left_available)); 615 std::max(right_available, left_available));
611 616
612 // If there is enough space for the popup on the right, show it there, 617 // If there is enough space for the popup on the right, show it there,
613 // otherwise choose the larger size. 618 // otherwise choose the larger size.
614 if (right_available >= popup_width || right_available >= left_available) 619 if (right_available >= popup_width || right_available >= left_available)
615 return std::make_pair(right_growth_start, popup_width); 620 return std::make_pair(right_growth_start, popup_width);
616 else 621 else
617 return std::make_pair(left_growth_end - popup_width, popup_width); 622 return std::make_pair(left_growth_end - popup_width, popup_width);
618 } 623 }
619 624
620 std::pair<int,int> AutofillPopupControllerImpl::CalculatePopupYAndHeight( 625 std::pair<int,int> AutofillPopupControllerImpl::CalculatePopupYAndHeight(
621 const gfx::Display& top_display, 626 const gfx::Display& top_display,
622 const gfx::Display& bottom_display, 627 const gfx::Display& bottom_display,
623 int popup_required_height) const { 628 int popup_required_height) const {
624 int topmost_display_y = top_display.bounds().y() * 629 int topmost_display_y = top_display.bounds().y() *
625 top_display.device_scale_factor(); 630 top_display.device_scale_factor();
626 int bottommost_display_y = bottom_display.GetSizeInPixel().height() + 631 int bottommost_display_y = bottom_display.GetSizeInPixel().height() +
627 (bottom_display.bounds().y() * 632 (bottom_display.bounds().y() *
628 bottom_display.device_scale_factor()); 633 bottom_display.device_scale_factor());
629 634
630 // Calculate the start coordinates for the popup if it is growing down or 635 // Calculate the start coordinates for the popup if it is growing down or
631 // the end position if it is growing up, capped to screen space. 636 // the end position if it is growing up, capped to screen space.
632 int top_growth_end = std::max(topmost_display_y, 637 int top_growth_end = std::max(topmost_display_y,
633 std::min(bottommost_display_y, 638 std::min(bottommost_display_y,
634 element_bounds().y())); 639 RoundedElementBounds().y()));
635 int bottom_growth_start = std::max(topmost_display_y, 640 int bottom_growth_start = std::max(topmost_display_y,
636 std::min(bottommost_display_y, 641 std::min(bottommost_display_y, RoundedElementBounds().bottom()));
637 element_bounds().bottom()));
638 642
639 int top_available = bottom_growth_start - topmost_display_y; 643 int top_available = bottom_growth_start - topmost_display_y;
640 int bottom_available = bottommost_display_y - top_growth_end; 644 int bottom_available = bottommost_display_y - top_growth_end;
641 645
642 // TODO(csharp): Restrict the popup height to what is available. 646 // TODO(csharp): Restrict the popup height to what is available.
643 if (bottom_available >= popup_required_height || 647 if (bottom_available >= popup_required_height ||
644 bottom_available >= top_available) { 648 bottom_available >= top_available) {
645 // The popup can appear below the field. 649 // The popup can appear below the field.
646 return std::make_pair(bottom_growth_start, popup_required_height); 650 return std::make_pair(bottom_growth_start, popup_required_height);
647 } else { 651 } else {
648 // The popup must appear above the field. 652 // The popup must appear above the field.
649 return std::make_pair(top_growth_end - popup_required_height, 653 return std::make_pair(top_growth_end - popup_required_height,
650 popup_required_height); 654 popup_required_height);
651 } 655 }
652 } 656 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698