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