password_generation_popup_view_views.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2014 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/password_generation_popup_view_views.h" 6 7#include "base/strings/string16.h" 8#include "chrome/browser/ui/autofill/password_generation_popup_controller.h" 9#include "ui/gfx/canvas.h" 10#include "ui/views/background.h" 11#include "ui/views/border.h" 12#include "ui/views/controls/label.h" 13#include "ui/views/controls/styled_label.h" 14#include "ui/views/layout/box_layout.h" 15#include "ui/views/widget/widget.h" 16 17namespace autofill { 18 19namespace { 20 21const SkColor kExplanatoryTextBackground = SkColorSetRGB(0xF5, 0xF5, 0xF5); 22const SkColor kExplanatoryTextColor = SkColorSetRGB(0x7F, 0x7F, 0x7F); 23const SkColor kDividerColor = SkColorSetRGB(0xE9, 0xE9, 0xE9); 24 25// The amount of whitespace that is present when there is no padding. Used 26// to get the proper spacing in the help section. 27const int kHelpVerticalOffset = 3; 28 29// Class that shows the password and the suggestion side-by-side. 30class PasswordRow : public views::View { 31 public: 32 PasswordRow(const base::string16& password, 33 const base::string16& suggestion, 34 const gfx::FontList& font_list, 35 int horizontal_border) { 36 set_clip_insets(gfx::Insets( 37 PasswordGenerationPopupView::kPasswordVerticalInset, 0, 38 PasswordGenerationPopupView::kPasswordVerticalInset, 0)); 39 views::BoxLayout* box_layout = new views::BoxLayout( 40 views::BoxLayout::kHorizontal, horizontal_border, 0, 0); 41 box_layout->set_spread_blank_space(true); 42 SetLayoutManager(box_layout); 43 44 password_label_ = new views::Label(password, font_list); 45 password_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 46 AddChildView(password_label_); 47 48 suggestion_label_ = new views::Label(suggestion, font_list); 49 suggestion_label_->SetHorizontalAlignment(gfx::ALIGN_RIGHT); 50 suggestion_label_->SetEnabledColor(kExplanatoryTextColor); 51 AddChildView(suggestion_label_); 52 } 53 virtual ~PasswordRow() {} 54 55 virtual bool HitTestRect(const gfx::Rect& rect) const OVERRIDE { 56 // Have parent do event handling. 57 return false; 58 } 59 60 private: 61 // Child views. Not owned. 62 views::Label* suggestion_label_; 63 views::Label* password_label_; 64 65 DISALLOW_COPY_AND_ASSIGN(PasswordRow); 66}; 67 68} // namespace 69 70PasswordGenerationPopupViewViews::PasswordGenerationPopupViewViews( 71 PasswordGenerationPopupController* controller, 72 views::Widget* observing_widget) 73 : AutofillPopupBaseView(controller, observing_widget), 74 password_view_(NULL), 75 controller_(controller) { 76 if (controller_->display_password()) 77 CreatePasswordView(); 78 79 help_label_ = new views::StyledLabel(controller_->HelpText(), this); 80 help_label_->SetBaseFontList(controller_->font_list()); 81 views::StyledLabel::RangeStyleInfo default_style; 82 default_style.color = kExplanatoryTextColor; 83 help_label_->SetDefaultStyle(default_style); 84 help_label_->AddStyleRange( 85 controller_->HelpTextLinkRange(), 86 views::StyledLabel::RangeStyleInfo::CreateForLink()); 87 88 help_label_->SetBoundsRect(controller_->help_bounds()); 89 help_label_->set_background( 90 views::Background::CreateSolidBackground(kExplanatoryTextBackground)); 91 help_label_->SetBorder(views::Border::CreateEmptyBorder( 92 controller_->kHelpVerticalPadding - kHelpVerticalOffset, 93 controller_->kHorizontalPadding, 94 0, 95 controller_->kHorizontalPadding)); 96 AddChildView(help_label_); 97 98 set_background(views::Background::CreateSolidBackground(kPopupBackground)); 99} 100 101PasswordGenerationPopupViewViews::~PasswordGenerationPopupViewViews() {} 102 103void PasswordGenerationPopupViewViews::CreatePasswordView() { 104 if (password_view_) 105 return; 106 107 password_view_ = new PasswordRow(controller_->password(), 108 controller_->SuggestedText(), 109 controller_->font_list(), 110 controller_->kHorizontalPadding); 111 AddChildView(password_view_); 112} 113 114void PasswordGenerationPopupViewViews::Show() { 115 DoShow(); 116} 117 118void PasswordGenerationPopupViewViews::Hide() { 119 // The controller is no longer valid after it hides us. 120 controller_ = NULL; 121 122 DoHide(); 123} 124 125void PasswordGenerationPopupViewViews::UpdateBoundsAndRedrawPopup() { 126 // Currently the UI can change from not offering a password to offering 127 // a password (e.g. the user is editing a generated password and deletes it), 128 // but it can't change the other way around. 129 if (controller_->display_password()) 130 CreatePasswordView(); 131 132 DoUpdateBoundsAndRedrawPopup(); 133} 134 135void PasswordGenerationPopupViewViews::PasswordSelectionUpdated() { 136 if (!password_view_) 137 return; 138 139 password_view_->set_background( 140 views::Background::CreateSolidBackground( 141 controller_->password_selected() ? 142 kHoveredBackgroundColor : 143 kPopupBackground)); 144} 145 146void PasswordGenerationPopupViewViews::Layout() { 147 if (password_view_) 148 password_view_->SetBoundsRect(controller_->password_bounds()); 149 150 help_label_->SetBoundsRect(controller_->help_bounds()); 151} 152 153void PasswordGenerationPopupViewViews::OnPaint(gfx::Canvas* canvas) { 154 if (!controller_) 155 return; 156 157 // Draw border and background. 158 views::View::OnPaint(canvas); 159 160 // Divider line needs to be drawn after OnPaint() otherwise the background 161 // will overwrite the divider. 162 if (password_view_) 163 canvas->FillRect(controller_->divider_bounds(), kDividerColor); 164} 165 166void PasswordGenerationPopupViewViews::StyledLabelLinkClicked( 167 const gfx::Range& range, int event_flags) { 168 controller_->OnSavedPasswordsLinkClicked(); 169} 170 171PasswordGenerationPopupView* PasswordGenerationPopupView::Create( 172 PasswordGenerationPopupController* controller) { 173 views::Widget* observing_widget = 174 views::Widget::GetTopLevelWidgetForNativeView( 175 controller->container_view()); 176 177 // If the top level widget can't be found, cancel the popup since we can't 178 // fully set it up. 179 if (!observing_widget) 180 return NULL; 181 182 return new PasswordGenerationPopupViewViews(controller, observing_widget); 183} 184 185} // namespace autofill 186