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.
5 #include "chrome/browser/ui/views/autofill/password_generation_popup_view_views.h"
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"
21 const SkColor kExplanatoryTextBackground
= SkColorSetRGB(0xF5, 0xF5, 0xF5);
22 const SkColor kExplanatoryTextColor
= SkColorSetRGB(0x7F, 0x7F, 0x7F);
23 const SkColor kDividerColor
= SkColorSetRGB(0xE9, 0xE9, 0xE9);
25 // The amount of whitespace that is present when there is no padding. Used
26 // to get the proper spacing in the help section.
27 const int kHelpVerticalOffset
= 3;
29 // Class that shows the password and the suggestion side-by-side.
30 class PasswordRow
: public views::View
{
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
);
44 password_label_
= new views::Label(password
, font_list
);
45 password_label_
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
46 AddChildView(password_label_
);
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_
);
53 virtual ~PasswordRow() {}
55 virtual bool HitTestRect(const gfx::Rect
& rect
) const OVERRIDE
{
56 // Have parent do event handling.
61 // Child views. Not owned.
62 views::Label
* suggestion_label_
;
63 views::Label
* password_label_
;
65 DISALLOW_COPY_AND_ASSIGN(PasswordRow
);
70 PasswordGenerationPopupViewViews::PasswordGenerationPopupViewViews(
71 PasswordGenerationPopupController
* controller
,
72 views::Widget
* observing_widget
)
73 : AutofillPopupBaseView(controller
, observing_widget
),
75 controller_(controller
) {
76 if (controller_
->display_password())
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());
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
,
95 controller_
->kHorizontalPadding
));
96 AddChildView(help_label_
);
98 set_background(views::Background::CreateSolidBackground(kPopupBackground
));
101 PasswordGenerationPopupViewViews::~PasswordGenerationPopupViewViews() {}
103 void PasswordGenerationPopupViewViews::CreatePasswordView() {
107 password_view_
= new PasswordRow(controller_
->password(),
108 controller_
->SuggestedText(),
109 controller_
->font_list(),
110 controller_
->kHorizontalPadding
);
111 AddChildView(password_view_
);
114 void PasswordGenerationPopupViewViews::Show() {
118 void PasswordGenerationPopupViewViews::Hide() {
119 // The controller is no longer valid after it hides us.
125 void 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();
132 DoUpdateBoundsAndRedrawPopup();
135 void PasswordGenerationPopupViewViews::PasswordSelectionUpdated() {
139 password_view_
->set_background(
140 views::Background::CreateSolidBackground(
141 controller_
->password_selected() ?
142 kHoveredBackgroundColor
:
146 void PasswordGenerationPopupViewViews::Layout() {
148 password_view_
->SetBoundsRect(controller_
->password_bounds());
150 help_label_
->SetBoundsRect(controller_
->help_bounds());
153 void PasswordGenerationPopupViewViews::OnPaint(gfx::Canvas
* canvas
) {
157 // Draw border and background.
158 views::View::OnPaint(canvas
);
160 // Divider line needs to be drawn after OnPaint() otherwise the background
161 // will overwrite the divider.
163 canvas
->FillRect(controller_
->divider_bounds(), kDividerColor
);
166 void PasswordGenerationPopupViewViews::StyledLabelLinkClicked(
167 const gfx::Range
& range
, int event_flags
) {
168 controller_
->OnSavedPasswordsLinkClicked();
171 PasswordGenerationPopupView
* PasswordGenerationPopupView::Create(
172 PasswordGenerationPopupController
* controller
) {
173 views::Widget
* observing_widget
=
174 views::Widget::GetTopLevelWidgetForNativeView(
175 controller
->container_view());
177 // If the top level widget can't be found, cancel the popup since we can't
179 if (!observing_widget
)
182 return new PasswordGenerationPopupViewViews(controller
, observing_widget
);
185 } // namespace autofill