Home | History | Annotate | Download | only in autofill
      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