screen_lock_view.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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/chromeos/login/screen_lock_view.h" 6 7#include "app/l10n_util.h" 8#include "app/resource_bundle.h" 9#include "base/utf_string_conversions.h" 10#include "chrome/browser/chromeos/login/helper.h" 11#include "chrome/browser/chromeos/login/rounded_rect_painter.h" 12#include "chrome/browser/chromeos/login/screen_locker.h" 13#include "chrome/browser/chromeos/login/user_manager.h" 14#include "chrome/browser/chromeos/login/user_view.h" 15#include "chrome/browser/chromeos/login/wizard_accessibility_helper.h" 16#include "chrome/browser/profile_manager.h" 17#include "chrome/common/notification_service.h" 18#include "grit/generated_resources.h" 19#include "grit/theme_resources.h" 20#include "views/background.h" 21#include "views/border.h" 22#include "views/controls/button/text_button.h" 23#include "views/controls/image_view.h" 24#include "views/controls/label.h" 25#include "views/grid_layout.h" 26 27namespace chromeos { 28 29namespace { 30 31const int kCornerRadius = 5; 32 33// A Textfield for password, which also sets focus to itself 34// when a mouse is clicked on it. This is necessary in screen locker 35// as mouse events are grabbed in the screen locker. 36class PasswordField : public views::Textfield { 37 public: 38 PasswordField() 39 : views::Textfield(views::Textfield::STYLE_PASSWORD) { 40 set_text_to_display_when_empty( 41 l10n_util::GetStringUTF16(IDS_LOGIN_EMPTY_PASSWORD_TEXT)); 42 } 43 44 // views::View overrides. 45 virtual bool OnMousePressed(const views::MouseEvent& e) { 46 RequestFocus(); 47 return false; 48 } 49 50 private: 51 DISALLOW_COPY_AND_ASSIGN(PasswordField); 52}; 53 54} // namespace 55 56using views::GridLayout; 57using login::kBorderSize; 58 59ScreenLockView::ScreenLockView(ScreenLocker* screen_locker) 60 : user_view_(NULL), 61 password_field_(NULL), 62 unlock_button_(NULL), 63 screen_locker_(screen_locker) { 64 DCHECK(screen_locker_); 65} 66 67void ScreenLockView::Init() { 68 registrar_.Add(this, 69 NotificationType::LOGIN_USER_IMAGE_CHANGED, 70 NotificationService::AllSources()); 71 72 user_view_ = new UserView(this, 73 false, // is_login 74 true); // need_background 75 views::View* main = new views::View(); 76 // Use rounded rect background. 77 views::Painter* painter = 78 CreateWizardPainter(&BorderDefinition::kUserBorder); 79 80 main->set_background( 81 views::Background::CreateBackgroundPainter(true, painter)); 82 main->set_border(CreateWizardBorder(&BorderDefinition::kUserBorder)); 83 84 // Password field. 85 password_field_ = new PasswordField(); 86 password_field_->SetController(this); 87 88 // Unlock button. 89 unlock_button_ = new views::TextButton( 90 this, l10n_util::GetString(IDS_UNLOCK_BUTTON)); 91 unlock_button_->set_tag(login::UNLOCK); 92 93 // User icon. 94 UserManager::User user = screen_locker_->user(); 95 user_view_->SetImage(user.image()); 96 97 // User name. 98 std::wstring text = UTF8ToWide(user.GetDisplayName()); 99 views::Label* label = new views::Label(text); 100 label->SetColor(login::kTextColor); 101 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 102 const gfx::Font& font = 103 rb.GetFont(ResourceBundle::LargeFont).DeriveFont(0, gfx::Font::BOLD); 104 label->SetFont(font); 105 106 // Layouts image, textfield and button components. 107 GridLayout* layout = new GridLayout(main); 108 main->SetLayoutManager(layout); 109 views::ColumnSet* column_set = layout->AddColumnSet(0); 110 column_set->AddPaddingColumn(0, kBorderSize); 111 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, 112 GridLayout::USE_PREF, 0, 0); 113 column_set->AddPaddingColumn(0, kBorderSize); 114 115 column_set = layout->AddColumnSet(1); 116 column_set->AddPaddingColumn(0, 5); 117 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, 118 GridLayout::USE_PREF, 0, 0); 119 column_set->AddPaddingColumn(0, 5); 120 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, 121 GridLayout::USE_PREF, 0, 0); 122 column_set->AddPaddingColumn(0, 5); 123 124 layout->AddPaddingRow(0, kBorderSize); 125 layout->StartRow(0, 0); 126 layout->AddView(user_view_); 127 layout->AddPaddingRow(0, kBorderSize); 128 layout->StartRow(0, 1); 129 layout->AddView(password_field_); 130 layout->AddView(unlock_button_); 131 layout->AddPaddingRow(0, 5); 132 133 unlock_button_->SetFocusable(true); 134 135 // Layouts the main view and the account label. 136 layout = new GridLayout(this); 137 SetLayoutManager(layout); 138 column_set = layout->AddColumnSet(0); 139 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, 140 GridLayout::USE_PREF, 0, 0); 141 142 column_set = layout->AddColumnSet(1); 143 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, 144 GridLayout::USE_PREF, 0, 0); 145 146 layout->StartRow(0, 0); 147 layout->AddView(main); 148 layout->StartRow(0, 1); 149 layout->AddView(label); 150} 151 152void ScreenLockView::ClearAndSetFocusToPassword() { 153 password_field_->RequestFocus(); 154 password_field_->SetText(string16()); 155} 156 157void ScreenLockView::SetSignoutEnabled(bool enabled) { 158 user_view_->SetSignoutEnabled(enabled); 159} 160 161gfx::Rect ScreenLockView::GetPasswordBoundsRelativeTo(const views::View* view) { 162 gfx::Point p; 163 views::View::ConvertPointToView(password_field_, view, &p); 164 return gfx::Rect(p, size()); 165} 166 167void ScreenLockView::SetEnabled(bool enabled) { 168 views::View::SetEnabled(enabled); 169 170 if (!enabled) { 171 user_view_->StartThrobber(); 172 // TODO(oshima): Re-enabling does not move the focus to the view 173 // that had a focus (issue http://crbug.com/43131). 174 // Move the focus to other field as a workaround. 175 unlock_button_->RequestFocus(); 176 } else { 177 user_view_->StopThrobber(); 178 } 179 unlock_button_->SetEnabled(enabled); 180 password_field_->SetEnabled(enabled); 181} 182 183void ScreenLockView::ButtonPressed(views::Button* sender, 184 const views::Event& event) { 185 if (sender->tag() == login::UNLOCK) 186 screen_locker_->Authenticate(password_field_->text()); 187 else 188 NOTREACHED(); 189} 190 191void ScreenLockView::OnSignout() { 192 screen_locker_->Signout(); 193} 194 195bool ScreenLockView::HandleKeystroke( 196 views::Textfield* sender, 197 const views::Textfield::Keystroke& keystroke) { 198 screen_locker_->ClearErrors(); 199 if (keystroke.GetKeyboardCode() == app::VKEY_RETURN) { 200 screen_locker_->Authenticate(password_field_->text()); 201 return true; 202 } 203 return false; 204} 205 206void ScreenLockView::Observe( 207 NotificationType type, 208 const NotificationSource& source, 209 const NotificationDetails& details) { 210 if (type != NotificationType::LOGIN_USER_IMAGE_CHANGED || !user_view_) 211 return; 212 213 UserManager::User* user = Details<UserManager::User>(details).ptr(); 214 if (screen_locker_->user().email() != user->email()) 215 return; 216 217 user_view_->SetImage(user->image()); 218} 219 220void ScreenLockView::ViewHierarchyChanged(bool is_add, 221 views::View* parent, 222 views::View* child) { 223 if (is_add && this == child) 224 WizardAccessibilityHelper::GetInstance()->MaybeEnableAccessibility(this); 225} 226} // namespace chromeos 227