Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(681)

Side by Side Diff: chrome/browser/chromeos/login/user_controller.cc

Issue 8436002: [cros] Remove Views implementation for login/OOBE. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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_controller.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/chromeos/login/existing_user_view.h"
12 #include "chrome/browser/chromeos/login/guest_user_view.h"
13 #include "chrome/browser/chromeos/login/helper.h"
14 #include "chrome/browser/chromeos/login/rounded_rect_painter.h"
15 #include "chrome/browser/chromeos/login/user_view.h"
16 #include "chrome/browser/chromeos/login/username_view.h"
17 #include "chrome/browser/chromeos/login/wizard_accessibility_helper.h"
18 #include "chrome/browser/chromeos/login/wizard_controller.h"
19 #include "chrome/browser/chromeos/user_cros_settings_provider.h"
20 #include "grit/generated_resources.h"
21 #include "grit/theme_resources.h"
22 #include "third_party/cros_system_api/window_manager/chromeos_wm_ipc_enums.h"
23 #include "ui/base/l10n/l10n_util.h"
24 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/gfx/canvas.h"
26 #include "views/background.h"
27 #include "views/controls/label.h"
28 #include "views/controls/throbber.h"
29 #include "views/focus/focus_manager.h"
30 #include "views/painter.h"
31 #include "views/widget/widget.h"
32
33 using views::Widget;
34
35 namespace chromeos {
36
37 namespace {
38
39 // Gap between the border around the image/buttons and user name.
40 const int kUserNameGap = 4;
41
42 // Approximate height of controls window, this constant is used in new user
43 // case to make border window size close to existing users.
44 #if defined(CROS_FONTS_USING_BCI)
45 const int kControlsHeight = 31;
46 #else
47 const int kControlsHeight = 28;
48 #endif
49
50 // Vertical interval between the image and the textfield.
51 const int kVerticalIntervalSize = 10;
52
53 void CloseWindow(views::Widget* window) {
54 if (window)
55 window->CloseNow();
56 }
57
58 } // namespace
59
60 // WidgetDelegate implementation for the Widget used for the controls.
61 class UserController::ControlsWidgetDelegate : public views::WidgetDelegate {
62 public:
63 ControlsWidgetDelegate(UserController* controller,
64 views::View* view)
65 : controller_(controller),
66 view_(view) {
67 }
68
69 virtual views::View* GetInitiallyFocusedView() OVERRIDE {
70 return view_;
71 }
72
73 virtual views::Widget* GetWidget() OVERRIDE {
74 return view_->GetWidget();
75 }
76 virtual const views::Widget* GetWidget() const OVERRIDE {
77 return view_->GetWidget();
78 }
79
80 private:
81 UserController* controller_;
82
83 // View to give focus to on show.
84 views::View* view_;
85
86 DISALLOW_COPY_AND_ASSIGN(ControlsWidgetDelegate);
87 };
88
89 using login::kBorderSize;
90 using login::kUserImageSize;
91
92 // static
93 const int UserController::kPadding = 30;
94
95 // Max size needed when an entry is not selected.
96 const int UserController::kUnselectedSize = 100;
97 const int UserController::kNewUserUnselectedSize = 42;
98
99 ////////////////////////////////////////////////////////////////////////////////
100 // UserController, public:
101
102 UserController::UserController(Delegate* delegate, bool is_guest)
103 : user_index_(-1),
104 is_user_selected_(false),
105 is_new_user_(!is_guest),
106 is_guest_(is_guest),
107 is_owner_(false),
108 show_name_tooltip_(false),
109 delegate_(delegate),
110 controls_widget_(NULL),
111 image_widget_(NULL),
112 border_window_(NULL),
113 label_widget_(NULL),
114 unselected_label_widget_(NULL),
115 user_view_(NULL),
116 label_view_(NULL),
117 unselected_label_view_(NULL),
118 user_input_(NULL),
119 throbber_host_(NULL) {
120 }
121
122 UserController::UserController(Delegate* delegate,
123 const UserManager::User& user)
124 : user_index_(-1),
125 is_user_selected_(false),
126 is_new_user_(false),
127 is_guest_(false),
128 // Empty 'cached_owner()' means that owner hasn't been cached yet, not
129 // that owner has an empty email.
130 is_owner_(user.email() == UserCrosSettingsProvider::cached_owner()),
131 show_name_tooltip_(false),
132 user_(user),
133 delegate_(delegate),
134 controls_widget_(NULL),
135 image_widget_(NULL),
136 border_window_(NULL),
137 label_widget_(NULL),
138 unselected_label_widget_(NULL),
139 user_view_(NULL),
140 label_view_(NULL),
141 unselected_label_view_(NULL),
142 user_input_(NULL),
143 throbber_host_(NULL) {
144 DCHECK(!user.email().empty());
145 }
146
147 UserController::~UserController() {
148 // Reset the widget delegate of every window to NULL, so the user
149 // controller will not get notified about the active window change.
150 // See also crosbug.com/7400.
151 CloseWindow(controls_widget_);
152 CloseWindow(image_widget_);
153 CloseWindow(border_window_);
154 CloseWindow(label_widget_);
155 CloseWindow(unselected_label_widget_);
156 }
157
158 void UserController::Init(int index,
159 int total_user_count,
160 bool need_browse_without_signin) {
161 int controls_height = 0;
162 int controls_width = 0;
163 SetupControlsWidget(index, &controls_width, &controls_height,
164 need_browse_without_signin);
165 image_widget_ = CreateImageWidget(index);
166 CreateBorderWindow(index, total_user_count, controls_width, controls_height);
167 label_widget_ = CreateLabelWidget(index, WM_IPC_WINDOW_LOGIN_LABEL);
168 unselected_label_widget_ =
169 CreateLabelWidget(index, WM_IPC_WINDOW_LOGIN_UNSELECTED_LABEL);
170 }
171
172 void UserController::ClearAndEnableFields() {
173 user_input_->EnableInputControls(true);
174 user_input_->ClearAndFocusControls();
175 StopThrobber();
176 }
177
178 void UserController::ClearAndEnablePassword() {
179 // Somehow focus manager thinks that textfield is still focused but the
180 // textfield doesn't know that. So we clear focus for focus manager so it
181 // sets focus on the textfield again.
182 // TODO(avayvod): Fix the actual issue.
183 views::FocusManager* focus_manager = controls_widget_->GetFocusManager();
184 if (focus_manager)
185 focus_manager->ClearFocus();
186 user_input_->EnableInputControls(true);
187 user_input_->ClearAndFocusPassword();
188 StopThrobber();
189 }
190
191 void UserController::EnableNameTooltip(bool enable) {
192 name_tooltip_enabled_ = enable;
193 string16 tooltip_text;
194 if (enable)
195 tooltip_text = GetNameTooltip();
196
197 if (user_view_)
198 user_view_->SetTooltipText(tooltip_text);
199 if (label_view_)
200 label_view_->SetTooltipText(tooltip_text);
201 if (unselected_label_view_)
202 unselected_label_view_->SetTooltipText(tooltip_text);
203 }
204
205 gfx::Rect UserController::GetMainInputScreenBounds() const {
206 return user_input_->GetMainInputScreenBounds();
207 }
208
209 void UserController::OnUserImageChanged(UserManager::User* user) {
210 if (user_.email() != user->email())
211 return;
212 user_.SetImage(user->image(), user->default_image_index());
213 // Controller might exist without windows,
214 // i.e. if user pod doesn't fit on the screen.
215 if (user_view_)
216 user_view_->SetImage(user_.image(), user_.image());
217 }
218
219 void UserController::SelectUserRelative(int shift) {
220 delegate_->SelectUser(user_index() + shift);
221 }
222
223 void UserController::StartThrobber() {
224 throbber_host_->StartThrobber();
225 }
226
227 void UserController::StopThrobber() {
228 throbber_host_->StopThrobber();
229 }
230
231 void UserController::UpdateUserCount(int index, int total_user_count) {
232 #if defined(TOOLKIT_USES_GTK)
233 user_index_ = index;
234 std::vector<int> params;
235 params.push_back(index);
236 params.push_back(total_user_count);
237 params.push_back(is_new_user_ ? kNewUserUnselectedSize : kUnselectedSize);
238 params.push_back(kPadding);
239 WmIpc::instance()->SetWindowType(
240 border_window_->GetNativeView(),
241 WM_IPC_WINDOW_LOGIN_BORDER,
242 &params);
243 #endif
244 }
245
246 std::string UserController::GetAccessibleUserLabel() {
247 if (is_new_user_)
248 return l10n_util::GetStringUTF8(IDS_ADD_USER);
249 if (is_guest_)
250 return l10n_util::GetStringUTF8(IDS_GUEST);
251 return user_.email();
252 }
253
254 ////////////////////////////////////////////////////////////////////////////////
255 // UserController, WidgetDelegate implementation:
256 //
257 views::Widget* UserController::GetWidget() {
258 return NULL;
259 }
260
261 const views::Widget* UserController::GetWidget() const {
262 return NULL;
263 }
264
265 ////////////////////////////////////////////////////////////////////////////////
266 // UserController, NewUserView::Delegate implementation:
267 //
268 void UserController::OnLogin(const std::string& username,
269 const std::string& password) {
270 if (is_new_user_)
271 user_.set_email(username);
272
273 user_input_->EnableInputControls(false);
274 StartThrobber();
275
276 delegate_->Login(this, UTF8ToUTF16(password));
277 }
278
279 void UserController::OnCreateAccount() {
280 user_input_->EnableInputControls(false);
281 StartThrobber();
282
283 delegate_->CreateAccount();
284 }
285
286 void UserController::OnStartEnterpriseEnrollment() {
287 delegate_->StartEnterpriseEnrollment();
288 }
289
290 void UserController::OnLoginAsGuest() {
291 user_input_->EnableInputControls(false);
292 StartThrobber();
293
294 delegate_->LoginAsGuest();
295 }
296
297 void UserController::ClearErrors() {
298 delegate_->ClearErrors();
299 }
300
301 void UserController::NavigateAway() {
302 SelectUserRelative(-1);
303 }
304
305 ////////////////////////////////////////////////////////////////////////////////
306 // UserController, UserView::Delegate implementation:
307 //
308 void UserController::OnLocaleChanged() {
309 // Update text tooltips on guest and new user pods.
310 if (is_guest_ || is_new_user_) {
311 if (name_tooltip_enabled_)
312 EnableNameTooltip(name_tooltip_enabled_);
313 }
314 label_view_->SetFont(GetLabelFont());
315 unselected_label_view_->SetFont(GetUnselectedLabelFont());
316 }
317
318 void UserController::OnRemoveUser() {
319 delegate_->RemoveUser(this);
320 }
321
322 bool UserController::IsUserSelected() const {
323 return is_user_selected_;
324 }
325
326 ////////////////////////////////////////////////////////////////////////////////
327 // UserController, views::Widget::Observer implementation:
328 //
329 void UserController::OnWidgetActivationChanged(views::Widget* widget,
330 bool active) {
331 is_user_selected_ = active;
332 if (active) {
333 delegate_->OnUserSelected(this);
334 user_view_->SetRemoveButtonVisible(
335 !is_new_user_ && !is_guest_ && !is_owner_);
336 } else {
337 user_view_->SetRemoveButtonVisible(false);
338 delegate_->ClearErrors();
339 }
340 }
341
342 ////////////////////////////////////////////////////////////////////////////////
343 // UserController, private:
344 //
345 void UserController::ConfigureAndShow(Widget* widget,
346 int index,
347 chromeos::WmIpcWindowType type,
348 views::View* contents_view) {
349 widget->SetContentsView(contents_view);
350
351 #if defined(TOOLKIT_USES_GTK)
352 std::vector<int> params;
353 params.push_back(index);
354 WmIpc::instance()->SetWindowType(
355 widget->GetNativeView(),
356 type,
357 &params);
358 #endif
359
360 widget->Show();
361 }
362
363 void UserController::SetupControlsWidget(
364 int index,
365 int* width, int* height,
366 bool need_browse_without_signin) {
367 views::View* control_view;
368 if (is_new_user_) {
369 NewUserView* new_user_view =
370 new NewUserView(this, need_browse_without_signin);
371 new_user_view->Init();
372 control_view = new_user_view;
373 user_input_ = new_user_view;
374 throbber_host_ = new_user_view;
375 } else if (is_guest_) {
376 GuestUserView* guest_user_view = new GuestUserView(this);
377 guest_user_view->RecreateFields();
378 control_view = guest_user_view;
379 user_input_ = guest_user_view;
380 throbber_host_ = guest_user_view;
381 } else {
382 ExistingUserView* existing_user_view = new ExistingUserView(this);
383 existing_user_view->RecreateFields();
384 control_view = existing_user_view;
385 user_input_ = existing_user_view;
386 throbber_host_ = existing_user_view;
387 }
388
389 *height = kControlsHeight;
390 *width = kUserImageSize;
391 if (is_new_user_) {
392 gfx::Size size = control_view->GetPreferredSize();
393 *width = size.width();
394 *height = size.height();
395 }
396
397 controls_widget_delegate_.reset(
398 new ControlsWidgetDelegate(this, control_view));
399 controls_widget_ = CreateControlsWidget(controls_widget_delegate_.get(),
400 gfx::Rect(*width, *height));
401 controls_widget_->AddObserver(this);
402 ConfigureAndShow(controls_widget_, index, WM_IPC_WINDOW_LOGIN_CONTROLS,
403 control_view);
404 }
405
406 Widget* UserController::CreateImageWidget(int index) {
407 user_view_ = new UserView(this, true, !is_new_user_);
408
409 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
410 if (is_guest_) {
411 SkBitmap* image = rb.GetBitmapNamed(IDR_LOGIN_GUEST);
412 user_view_->SetImage(*image, *image);
413 } else if (is_new_user_) {
414 SkBitmap* image = rb.GetBitmapNamed(IDR_LOGIN_ADD_USER);
415 SkBitmap* image_hover = rb.GetBitmapNamed(IDR_LOGIN_ADD_USER_HOVER);
416 user_view_->SetImage(*image, *image_hover);
417 } else {
418 user_view_->SetImage(user_.image(), user_.image());
419 }
420
421 Widget* widget =
422 CreateClickNotifyingWidget(this,
423 gfx::Rect(user_view_->GetPreferredSize()));
424 widget->AddObserver(this);
425 ConfigureAndShow(widget, index, WM_IPC_WINDOW_LOGIN_IMAGE, user_view_);
426
427 return widget;
428 }
429
430 void UserController::CreateBorderWindow(int index,
431 int total_user_count,
432 int controls_width,
433 int controls_height) {
434 // New user login controls window is much higher than existing user's controls
435 // window so window manager will place the control instead of image window.
436 // New user will have 0 size border.
437 int width = controls_width;
438 int height = controls_height;
439 if (!is_new_user_) {
440 width += kBorderSize * 2;
441 height += 2 * kBorderSize + kUserImageSize + kVerticalIntervalSize;
442 }
443
444 border_window_ = new Widget;
445 Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
446 params.transparent = true;
447 params.bounds = gfx::Rect(0, 0, width, height);
448 border_window_->Init(params);
449 if (!is_new_user_) {
450 views::View* background_view = new views::View();
451 views::Painter* painter = CreateWizardPainter(
452 &BorderDefinition::kUserBorder);
453 background_view->set_background(
454 views::Background::CreateBackgroundPainter(true, painter));
455 border_window_->SetContentsView(background_view);
456 }
457 UpdateUserCount(index, total_user_count);
458
459 GdkWindow* gdk_window = border_window_->GetNativeView()->window;
460 gdk_window_set_back_pixmap(gdk_window, NULL, false);
461
462 border_window_->Show();
463 }
464
465 Widget* UserController::CreateLabelWidget(int index, WmIpcWindowType type) {
466 string16 text;
467 if (is_guest_) {
468 text = string16();
469 } else if (is_new_user_) {
470 // Add user should have label only in activated state.
471 // When new user is the only, label is not needed.
472 if (type == WM_IPC_WINDOW_LOGIN_LABEL && index != 0)
473 text = l10n_util::GetStringUTF16(IDS_ADD_USER);
474 } else {
475 text = UTF8ToUTF16(user_.GetDisplayName());
476 }
477
478 views::Label* label = NULL;
479
480 if (is_new_user_) {
481 label = new views::Label(text);
482 } else if (type == WM_IPC_WINDOW_LOGIN_LABEL) {
483 label = UsernameView::CreateShapedUsernameView(UTF16ToWide(text), false);
484 } else {
485 DCHECK(type == WM_IPC_WINDOW_LOGIN_UNSELECTED_LABEL);
486 // TODO(altimofeev): switch to the rounded username view.
487 label = UsernameView::CreateShapedUsernameView(
488 UTF16ToWideHack(text), true);
489 }
490
491 const gfx::Font& font = (type == WM_IPC_WINDOW_LOGIN_LABEL) ?
492 GetLabelFont() : GetUnselectedLabelFont();
493 label->SetFont(font);
494 label->SetAutoColorReadabilityEnabled(false);
495 label->SetEnabledColor(login::kTextColor);
496
497 if (type == WM_IPC_WINDOW_LOGIN_LABEL)
498 label_view_ = label;
499 else
500 unselected_label_view_ = label;
501
502 int width = (type == WM_IPC_WINDOW_LOGIN_LABEL) ?
503 kUserImageSize : kUnselectedSize;
504 if (is_new_user_) {
505 // Make label as small as possible to don't show tooltip.
506 width = 0;
507 }
508 int height = (type == WM_IPC_WINDOW_LOGIN_LABEL) ?
509 login::kSelectedLabelHeight : login::kUnselectedLabelHeight;
510 Widget* widget = CreateClickNotifyingWidget(this,
511 gfx::Rect(0, 0, width, height));
512 ConfigureAndShow(widget, index, type, label);
513 return widget;
514 }
515
516 gfx::Font UserController::GetLabelFont() {
517 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
518 return rb.GetFont(ResourceBundle::MediumBoldFont).DeriveFont(
519 kSelectedUsernameFontDelta);
520 }
521
522 gfx::Font UserController::GetUnselectedLabelFont() {
523 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
524 return rb.GetFont(ResourceBundle::BaseFont).DeriveFont(
525 kUnselectedUsernameFontDelta, gfx::Font::BOLD);
526 }
527
528 string16 UserController::GetNameTooltip() const {
529 if (is_new_user_)
530 return l10n_util::GetStringUTF16(IDS_ADD_USER);
531 else if (is_guest_)
532 return l10n_util::GetStringUTF16(IDS_GO_INCOGNITO_BUTTON);
533 else
534 return UTF8ToUTF16(user_.GetNameTooltip());
535 }
536
537 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/user_controller.h ('k') | chrome/browser/chromeos/login/user_controller_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698