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