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 "ui/base/resource/resource_bundle.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/gfx/native_widget_types.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/point.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/text_utils.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/border.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace autofill { 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutofillPopupViewViews::AutofillPopupViewViews( 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AutofillPopupController* controller, views::Widget* observing_widget) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : AutofillPopupBaseView(controller, observing_widget), 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller_(controller) {} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AutofillPopupViewViews::~AutofillPopupViewViews() {} 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AutofillPopupViewViews::Show() { 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoShow(); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillPopupViewViews::Hide() { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The controller is no longer valid after it hides us. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller_ = NULL; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoHide(); 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AutofillPopupViewViews::UpdateBoundsAndRedrawPopup() { 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoUpdateBoundsAndRedrawPopup(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillPopupViewViews::OnPaint(gfx::Canvas* canvas) { 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!controller_) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->DrawColor(kPopupBackground); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPaintBorder(canvas); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < controller_->names().size(); ++i) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect line_rect = controller_->GetRowBounds(i); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (controller_->identifiers()[i] == POPUP_ITEM_ID_SEPARATOR) { 556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) canvas->FillRect(line_rect, kItemTextColor); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawAutofillEntry(canvas, i, line_rect); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillPopupViewViews::InvalidateRow(size_t row) { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SchedulePaintInRect(controller_->GetRowBounds(row)); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillPopupViewViews::DrawAutofillEntry(gfx::Canvas* canvas, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& entry_rect) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller_->selected_line() == index) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->FillRect(entry_rect, kHoveredBackgroundColor); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bool is_rtl = controller_->IsRTL(); 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int value_text_width = 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::GetStringWidth(controller_->names()[index], 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller_->GetNameFontListForRow(index)); 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int value_content_x = is_rtl ? 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry_rect.width() - value_text_width - kEndPadding : kEndPadding; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) canvas->DrawStringRectWithFlags( 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller_->names()[index], 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller_->GetNameFontListForRow(index), 827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) controller_->IsWarning(index) ? kWarningTextColor : kValueTextColor, 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect(value_content_x, 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry_rect.y(), 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) value_text_width, 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry_rect.height()), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Canvas::TEXT_ALIGN_CENTER); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use this to figure out where all the other Autofill items should be placed. 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x_align_left = is_rtl ? kEndPadding : entry_rect.width() - kEndPadding; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Draw the Autofill icon, if one exists 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int row_height = controller_->GetRowBounds(index).height(); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!controller_->icons()[index].empty()) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int icon = controller_->GetIconResourceID(controller_->icons()[index]); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, icon); 980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const gfx::ImageSkia* image = rb.GetImageSkiaNamed(icon); 990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int icon_y = entry_rect.y() + (row_height - image->height()) / 2; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) x_align_left += is_rtl ? 0 : -image->width(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) canvas->DrawImageInt(*image, x_align_left, icon_y); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) x_align_left += is_rtl ? image->width() + kIconPadding : -kIconPadding; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Draw the name text. 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int subtext_width = 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::GetStringWidth(controller_->subtexts()[index], 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller_->subtext_font_list()); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!is_rtl) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) x_align_left -= subtext_width; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) canvas->DrawStringRectWithFlags( 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller_->subtexts()[index], 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller_->subtext_font_list(), 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kItemTextColor, 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect(x_align_left, 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry_rect.y(), 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) subtext_width, 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry_rect.height()), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Canvas::TEXT_ALIGN_CENTER); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AutofillPopupView* AutofillPopupView::Create( 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AutofillPopupController* controller) { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::Widget* observing_widget = 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::Widget::GetTopLevelWidgetForNativeView( 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) controller->container_view()); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the top level widget can't be found, cancel the popup since we can't 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // fully set it up. 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!observing_widget) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return new AutofillPopupViewViews(controller, observing_widget); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace autofill 141