15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/autofill/autofill_popup_view_views.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/autofill/autofill_popup_controller.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/autofill/core/browser/popup_item_ids.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/gfx/native_widget_types.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/point.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/text_utils.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/border.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace autofill {
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutofillPopupViewViews::AutofillPopupViewViews(
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    AutofillPopupController* controller, views::Widget* observing_widget)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : AutofillPopupBaseView(controller, observing_widget),
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      controller_(controller) {}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AutofillPopupViewViews::~AutofillPopupViewViews() {}
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AutofillPopupViewViews::Show() {
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DoShow();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillPopupViewViews::Hide() {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The controller is no longer valid after it hides us.
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller_ = NULL;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DoHide();
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AutofillPopupViewViews::UpdateBoundsAndRedrawPopup() {
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DoUpdateBoundsAndRedrawPopup();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillPopupViewViews::OnPaint(gfx::Canvas* canvas) {
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!controller_)
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->DrawColor(kPopupBackground);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnPaintBorder(canvas);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < controller_->names().size(); ++i) {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect line_rect = controller_->GetRowBounds(i);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (controller_->identifiers()[i] == POPUP_ITEM_ID_SEPARATOR) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas->DrawRect(line_rect, kItemTextColor);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawAutofillEntry(canvas, i, line_rect);
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillPopupViewViews::InvalidateRow(size_t row) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulePaintInRect(controller_->GetRowBounds(row));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillPopupViewViews::DrawAutofillEntry(gfx::Canvas* canvas,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               int index,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const gfx::Rect& entry_rect) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (controller_->selected_line() == index)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->FillRect(entry_rect, kHoveredBackgroundColor);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const bool is_rtl = controller_->IsRTL();
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int value_text_width =
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gfx::GetStringWidth(controller_->names()[index],
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          controller_->GetNameFontListForRow(index));
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int value_content_x = is_rtl ?
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entry_rect.width() - value_text_width - kEndPadding : kEndPadding;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  canvas->DrawStringRectWithFlags(
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller_->names()[index],
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      controller_->GetNameFontListForRow(index),
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      controller_->IsWarning(index) ? kWarningTextColor : kValueTextColor,
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gfx::Rect(value_content_x,
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                entry_rect.y(),
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                value_text_width,
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                entry_rect.height()),
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Canvas::TEXT_ALIGN_CENTER);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use this to figure out where all the other Autofill items should be placed.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int x_align_left = is_rtl ? kEndPadding : entry_rect.width() - kEndPadding;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the Autofill icon, if one exists
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int row_height = controller_->GetRowBounds(index).height();
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!controller_->icons()[index].empty()) {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int icon = controller_->GetIconResourceID(controller_->icons()[index]);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(-1, icon);
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const gfx::ImageSkia* image = rb.GetImageSkiaNamed(icon);
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int icon_y = entry_rect.y() + (row_height - image->height()) / 2;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    x_align_left += is_rtl ? 0 : -image->width();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    canvas->DrawImageInt(*image, x_align_left, icon_y);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    x_align_left += is_rtl ? image->width() + kIconPadding : -kIconPadding;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Draw the name text.
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int subtext_width =
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gfx::GetStringWidth(controller_->subtexts()[index],
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          controller_->subtext_font_list());
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!is_rtl)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    x_align_left -= subtext_width;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  canvas->DrawStringRectWithFlags(
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller_->subtexts()[index],
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      controller_->subtext_font_list(),
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kItemTextColor,
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gfx::Rect(x_align_left,
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                entry_rect.y(),
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                subtext_width,
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                entry_rect.height()),
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Canvas::TEXT_ALIGN_CENTER);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AutofillPopupView* AutofillPopupView::Create(
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AutofillPopupController* controller) {
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  views::Widget* observing_widget =
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      views::Widget::GetTopLevelWidgetForNativeView(
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          controller->container_view());
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If the top level widget can't be found, cancel the popup since we can't
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // fully set it up.
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!observing_widget)
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new AutofillPopupViewViews(controller, observing_widget);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace autofill
142