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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/views/autofill/autofill_popup_view_views.h" 6 7 #include "chrome/browser/ui/autofill/autofill_popup_controller.h" 8 #include "components/autofill/core/browser/popup_item_ids.h" 9 #include "grit/ui_resources.h" 10 #include "ui/base/resource/resource_bundle.h" 11 #include "ui/events/keycodes/keyboard_codes.h" 12 #include "ui/gfx/canvas.h" 13 #include "ui/gfx/image/image.h" 14 #include "ui/gfx/native_widget_types.h" 15 #include "ui/gfx/point.h" 16 #include "ui/gfx/rect.h" 17 #include "ui/gfx/text_utils.h" 18 #include "ui/views/border.h" 19 #include "ui/views/widget/widget.h" 20 21 namespace autofill { 22 23 AutofillPopupViewViews::AutofillPopupViewViews( 24 AutofillPopupController* controller, views::Widget* observing_widget) 25 : AutofillPopupBaseView(controller, observing_widget), 26 controller_(controller) {} 27 28 AutofillPopupViewViews::~AutofillPopupViewViews() {} 29 30 void AutofillPopupViewViews::Show() { 31 DoShow(); 32 } 33 34 void AutofillPopupViewViews::Hide() { 35 // The controller is no longer valid after it hides us. 36 controller_ = NULL; 37 38 DoHide(); 39 } 40 41 void AutofillPopupViewViews::UpdateBoundsAndRedrawPopup() { 42 DoUpdateBoundsAndRedrawPopup(); 43 } 44 45 void AutofillPopupViewViews::OnPaint(gfx::Canvas* canvas) { 46 if (!controller_) 47 return; 48 49 canvas->DrawColor(kPopupBackground); 50 OnPaintBorder(canvas); 51 52 for (size_t i = 0; i < controller_->names().size(); ++i) { 53 gfx::Rect line_rect = controller_->GetRowBounds(i); 54 55 if (controller_->identifiers()[i] == POPUP_ITEM_ID_SEPARATOR) { 56 canvas->DrawRect(line_rect, kItemTextColor); 57 } else { 58 DrawAutofillEntry(canvas, i, line_rect); 59 } 60 } 61 } 62 63 void AutofillPopupViewViews::InvalidateRow(size_t row) { 64 SchedulePaintInRect(controller_->GetRowBounds(row)); 65 } 66 67 void AutofillPopupViewViews::DrawAutofillEntry(gfx::Canvas* canvas, 68 int index, 69 const gfx::Rect& entry_rect) { 70 if (controller_->selected_line() == index) 71 canvas->FillRect(entry_rect, kHoveredBackgroundColor); 72 73 const bool is_rtl = controller_->IsRTL(); 74 const int value_text_width = 75 gfx::GetStringWidth(controller_->names()[index], 76 controller_->GetNameFontListForRow(index)); 77 const int value_content_x = is_rtl ? 78 entry_rect.width() - value_text_width - kEndPadding : kEndPadding; 79 80 canvas->DrawStringRectWithFlags( 81 controller_->names()[index], 82 controller_->GetNameFontListForRow(index), 83 controller_->IsWarning(index) ? kWarningTextColor : kValueTextColor, 84 gfx::Rect(value_content_x, 85 entry_rect.y(), 86 value_text_width, 87 entry_rect.height()), 88 gfx::Canvas::TEXT_ALIGN_CENTER); 89 90 // Use this to figure out where all the other Autofill items should be placed. 91 int x_align_left = is_rtl ? kEndPadding : entry_rect.width() - kEndPadding; 92 93 // Draw the Autofill icon, if one exists 94 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 95 int row_height = controller_->GetRowBounds(index).height(); 96 if (!controller_->icons()[index].empty()) { 97 int icon = controller_->GetIconResourceID(controller_->icons()[index]); 98 DCHECK_NE(-1, icon); 99 const gfx::ImageSkia* image = rb.GetImageSkiaNamed(icon); 100 int icon_y = entry_rect.y() + (row_height - image->height()) / 2; 101 102 x_align_left += is_rtl ? 0 : -image->width(); 103 104 canvas->DrawImageInt(*image, x_align_left, icon_y); 105 106 x_align_left += is_rtl ? image->width() + kIconPadding : -kIconPadding; 107 } 108 109 // Draw the name text. 110 const int subtext_width = 111 gfx::GetStringWidth(controller_->subtexts()[index], 112 controller_->subtext_font_list()); 113 if (!is_rtl) 114 x_align_left -= subtext_width; 115 116 canvas->DrawStringRectWithFlags( 117 controller_->subtexts()[index], 118 controller_->subtext_font_list(), 119 kItemTextColor, 120 gfx::Rect(x_align_left, 121 entry_rect.y(), 122 subtext_width, 123 entry_rect.height()), 124 gfx::Canvas::TEXT_ALIGN_CENTER); 125 } 126 127 AutofillPopupView* AutofillPopupView::Create( 128 AutofillPopupController* controller) { 129 views::Widget* observing_widget = 130 views::Widget::GetTopLevelWidgetForNativeView( 131 controller->container_view()); 132 133 // If the top level widget can't be found, cancel the popup since we can't 134 // fully set it up. 135 if (!observing_widget) 136 return NULL; 137 138 return new AutofillPopupViewViews(controller, observing_widget); 139 } 140 141 } // namespace autofill 142