user_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/user_view.h" 6 7#include "app/l10n_util.h" 8#include "app/resource_bundle.h" 9#include "chrome/browser/chromeos/login/helper.h" 10#include "grit/generated_resources.h" 11#include "views/controls/button/menu_button.h" 12#include "views/controls/button/text_button.h" 13#include "views/controls/image_view.h" 14#include "views/controls/label.h" 15#include "views/controls/menu/menu_2.h" 16#include "views/controls/throbber.h" 17 18namespace { 19 20// Background color of the login status label and signout button. 21const SkColor kSignoutBackgroundColor = 0xFF007700; 22 23// Left margin to the "Active User" text. 24const int kSignoutLeftOffset = 10; 25 26// Padding between menu button and left right image corner. 27const int kMenuButtonPadding = 4; 28 29const int kIdRemove = 1; 30const int kIdChangePhoto = 2; 31 32} // namespace 33 34namespace chromeos { 35 36using login::kBackgroundColor; 37using login::kBorderSize; 38using login::kTextColor; 39using login::kUserImageSize; 40 41// The view that shows the Sign out button below the user's image. 42class SignoutView : public views::View { 43 public: 44 explicit SignoutView(views::ButtonListener* listener) { 45 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 46 const gfx::Font& font = rb.GetFont(ResourceBundle::SmallFont); 47 48 active_user_label_ = new views::Label( 49 l10n_util::GetString(IDS_SCREEN_LOCK_ACTIVE_USER)); 50 active_user_label_->SetFont(font); 51 active_user_label_->SetColor(kTextColor); 52 53 signout_button_ = new views::TextButton( 54 listener, l10n_util::GetString(IDS_SCREEN_LOCK_SIGN_OUT)); 55 signout_button_->SetFont(font); 56 signout_button_->SetEnabledColor(kTextColor); 57 signout_button_->SetNormalHasBorder(false); 58 signout_button_->set_tag(login::SIGN_OUT); 59 signout_button_->SetFocusable(true); 60 61 AddChildView(active_user_label_); 62 AddChildView(signout_button_); 63 64 set_background(views::Background::CreateSolidBackground( 65 kSignoutBackgroundColor)); 66 } 67 68 // views::View overrides. 69 virtual void Layout() { 70 gfx::Size label = active_user_label_->GetPreferredSize(); 71 gfx::Size button = signout_button_->GetPreferredSize(); 72 active_user_label_->SetBounds(kSignoutLeftOffset, 73 (height() - label.height()) / 2, 74 label.width(), label.height()); 75 signout_button_->SetBounds( 76 width() - button.width(), (height() - button.height()) / 2, 77 button.width(), button.height()); 78 } 79 80 virtual gfx::Size GetPreferredSize() { 81 gfx::Size label = active_user_label_->GetPreferredSize(); 82 gfx::Size button = signout_button_->GetPreferredSize(); 83 return gfx::Size(label.width() + button.width(), 84 std::max(label.height(), button.height())); 85 } 86 87 views::Button* signout_button() { return signout_button_; } 88 89 private: 90 friend class UserView; 91 92 views::Label* active_user_label_; 93 views::TextButton* signout_button_; 94 95 DISALLOW_COPY_AND_ASSIGN(SignoutView); 96}; 97 98UserView::UserView(Delegate* delegate, bool is_login) 99 : delegate_(delegate), 100 signout_view_(NULL), 101 image_view_(new views::ImageView()), 102 throbber_(CreateDefaultSmoothedThrobber()), 103 menu_button_(NULL) { 104 DCHECK(delegate); 105 if (!is_login) 106 signout_view_ = new SignoutView(this); 107 if (is_login) 108 menu_button_ = new views::MenuButton(NULL, std::wstring(), this, true); 109 110 Init(); 111} 112 113void UserView::Init() { 114 image_view_->set_background( 115 views::Background::CreateSolidBackground(kBackgroundColor)); 116 if (throbber_) { 117 int w = throbber_->GetPreferredSize().width(); 118 int h = throbber_->GetPreferredSize().height(); 119 throbber_->SetBounds(kUserImageSize / 2 - w / 2, 120 kUserImageSize / 2 - h / 2 , w, h); 121 // Throbber should be actually hidden while stopped so tooltip manager 122 // doesn't find it. 123 throbber_->SetVisible(false); 124 image_view_->AddChildView(throbber_); 125 } 126 127 // UserView's layout never changes, so let's layout once here. 128 image_view_->SetBounds(0, 0, kUserImageSize, kUserImageSize); 129 AddChildView(image_view_); 130 if (signout_view_) { 131 signout_view_->SetBounds(0, kUserImageSize, kUserImageSize, 132 signout_view_->GetPreferredSize().height()); 133 AddChildView(signout_view_); 134 } 135 if (menu_button_) { 136 int w = menu_button_->GetPreferredSize().width(); 137 int h = menu_button_->GetPreferredSize().height(); 138 menu_button_->SetBounds(kUserImageSize - w - kMenuButtonPadding, 139 kMenuButtonPadding, w, h); 140 menu_button_->SetVisible(false); 141 AddChildView(menu_button_); 142 } 143} 144 145void UserView::SetImage(const SkBitmap& image) { 146 int desired_size = std::min(image.width(), image.height()); 147 // Desired size is not preserved if it's greater than 75% of kUserImageSize. 148 if (desired_size * 4 > 3 * kUserImageSize) 149 desired_size = kUserImageSize; 150 image_view_->SetImageSize(gfx::Size(desired_size, desired_size)); 151 image_view_->SetImage(image); 152} 153 154void UserView::SetTooltipText(const std::wstring& text) { 155 DCHECK(image_view_); 156 image_view_->SetTooltipText(text); 157} 158 159void UserView::StartThrobber() { 160 throbber_->SetVisible(true); 161 throbber_->Start(); 162} 163 164void UserView::StopThrobber() { 165 throbber_->Stop(); 166 throbber_->SetVisible(false); 167} 168 169gfx::Size UserView::GetPreferredSize() { 170 return gfx::Size( 171 kUserImageSize, 172 kUserImageSize + 173 (signout_view_ ? signout_view_->GetPreferredSize().height() : 0)); 174} 175 176void UserView::SetSignoutEnabled(bool enabled) { 177 DCHECK(signout_view_); 178 signout_view_->signout_button_->SetEnabled(enabled); 179} 180 181void UserView::ButtonPressed(views::Button* sender, const views::Event& event) { 182 DCHECK(delegate_); 183 if (sender->tag() == login::SIGN_OUT) 184 delegate_->OnSignout(); 185} 186 187void UserView::SetMenuVisible(bool flag) { 188 DCHECK(menu_button_); 189 menu_button_->SetVisible(flag); 190} 191 192void UserView::BuildMenu() { 193 menu_model_.reset(new menus::SimpleMenuModel(this)); 194 menu_model_->AddItemWithStringId(kIdRemove, IDS_LOGIN_REMOVE); 195 menu_model_->AddItemWithStringId(kIdChangePhoto, IDS_LOGIN_CHANGE_PHOTO); 196 menu_.reset(new views::Menu2(menu_model_.get())); 197} 198 199void UserView::RunMenu(View* source, const gfx::Point& pt) { 200 if (!menu_.get()) 201 BuildMenu(); 202 203 menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); 204} 205 206bool UserView::IsCommandIdChecked(int command_id) const { 207 return false; 208} 209 210bool UserView::IsCommandIdEnabled(int command_id) const { 211 // TODO(dpolukhin): implement and enable change photo. 212 return command_id != kIdChangePhoto; 213} 214 215bool UserView::GetAcceleratorForCommandId(int command_id, 216 menus::Accelerator* accelerator) { 217 return false; 218} 219 220void UserView::ExecuteCommand(int command_id) { 221 switch (command_id) { 222 case kIdRemove: 223 delegate_->OnRemoveUser(); 224 break; 225 226 case kIdChangePhoto: 227 delegate_->OnChangePhoto(); 228 break; 229 } 230} 231 232} // namespace chromeos 233