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