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