Added Sign In button to Guest pod.

BUG=chromium-os:7161
TEST=Verify that clicking on Guest entry now selects it and clicking on Sign In button goes to Guest mode. Verify that keyboard navigation works as expected.

Review URL: http://codereview.chromium.org/3547015

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61641 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chromeos/login/existing_user_view.cc b/chrome/browser/chromeos/login/existing_user_view.cc
index db5e555f..1f1e6dc 100644
--- a/chrome/browser/chromeos/login/existing_user_view.cc
+++ b/chrome/browser/chromeos/login/existing_user_view.cc
@@ -45,18 +45,17 @@
       : Textfield(style),
         controller_(controller) {}
 
-  // Overridden from View:
+  // Overridden from views::View:
   virtual bool OnKeyPressed(const views::KeyEvent& e) {
     if (e.GetKeyCode() == app::VKEY_TAB) {
       int index = controller_->user_index() + (e.IsShiftDown() ? -1 : 1);
-      controller_->SelectUser(index, false);
+      controller_->SelectUser(index);
       return true;
     } else {
       return false;
     }
   }
 
-  // Overridden from views::Textfield:
   virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e) {
     if (e.GetKeyCode() == app::VKEY_TAB)
       return true;
diff --git a/chrome/browser/chromeos/login/guest_user_view.cc b/chrome/browser/chromeos/login/guest_user_view.cc
new file mode 100644
index 0000000..c26db80
--- /dev/null
+++ b/chrome/browser/chromeos/login/guest_user_view.cc
@@ -0,0 +1,113 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/login/guest_user_view.h"
+
+#include "app/l10n_util.h"
+#include "chrome/browser/chromeos/login/user_controller.h"
+#include "chrome/browser/chromeos/login/wizard_accessibility_helper.h"
+#include "grit/generated_resources.h"
+
+namespace chromeos {
+
+// Button with custom processing for Tab/Shift+Tab to select entries.
+class UserEntryButton : public views::NativeButton {
+ public:
+  UserEntryButton(UserController* controller,
+                  const std::wstring& label)
+      : NativeButton(controller, label),
+        controller_(controller) {}
+
+  // Overridden from views::View:
+  virtual bool OnKeyPressed(const views::KeyEvent& e) {
+    if (e.GetKeyCode() == app::VKEY_TAB) {
+      int index = controller_->user_index() + (e.IsShiftDown() ? -1 : 1);
+      controller_->SelectUser(index);
+      return true;
+    }
+    return views::NativeButton::OnKeyPressed(e);
+  }
+
+  virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e) {
+    if (e.GetKeyCode() == app::VKEY_TAB)
+      return true;
+    return views::NativeButton::SkipDefaultKeyEventProcessing(e);
+  }
+
+ private:
+  UserController* controller_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserEntryButton);
+};
+
+
+GuestUserView::GuestUserView(UserController* uc)
+    : submit_button_(NULL),
+      user_controller_(uc),
+      accel_enable_accessibility_(
+          WizardAccessibilityHelper::GetAccelerator()),
+      accel_login_off_the_record_(
+          views::Accelerator(app::VKEY_B, false, false, true)),
+      accel_previous_pod_by_arrow_(
+          views::Accelerator(app::VKEY_LEFT, false, false, false)),
+      accel_next_pod_by_arrow_(
+          views::Accelerator(app::VKEY_RIGHT, false, false, false)) {
+  AddAccelerator(accel_enable_accessibility_);
+  AddAccelerator(accel_login_off_the_record_);
+  AddAccelerator(accel_previous_pod_by_arrow_);
+  AddAccelerator(accel_next_pod_by_arrow_);
+}
+
+void GuestUserView::RecreateFields() {
+  delete submit_button_;
+  submit_button_ = new UserEntryButton(
+      user_controller_,
+      l10n_util::GetString(IDS_LOGIN_BUTTON));
+  AddChildView(submit_button_);
+  Layout();
+  SchedulePaint();
+}
+
+void GuestUserView::FocusSignInButton() {
+  if (GetFocusManager())
+    submit_button_->RequestFocus();
+}
+
+bool GuestUserView::AcceleratorPressed(
+    const views::Accelerator& accelerator) {
+  if (accelerator == accel_login_off_the_record_)
+    user_controller_->OnLoginOffTheRecord();
+  else if (accelerator == accel_enable_accessibility_)
+    WizardAccessibilityHelper::GetInstance()->EnableAccessibility(this);
+  else if (accelerator == accel_previous_pod_by_arrow_)
+    user_controller_->SelectUser(user_controller_->user_index() - 1);
+  else if (accelerator == accel_next_pod_by_arrow_)
+    user_controller_->SelectUser(user_controller_->user_index() + 1);
+  else
+    return false;
+  return true;
+}
+
+void GuestUserView::ViewHierarchyChanged(bool is_add,
+                                         views::View* parent,
+                                         views::View* child) {
+  if (is_add && this == child)
+    WizardAccessibilityHelper::GetInstance()->MaybeEnableAccessibility(this);
+}
+
+void GuestUserView::OnLocaleChanged() {
+  RecreateFields();
+}
+
+void GuestUserView::Layout() {
+  gfx::Size submit_button_size = submit_button_->GetPreferredSize();
+  int submit_button_x = (width() - submit_button_size.width()) / 2;
+  int submit_button_y = (height() - submit_button_size.height()) / 2;
+  submit_button_->SetBounds(submit_button_x,
+                            submit_button_y,
+                            submit_button_size.width(),
+                            submit_button_size.height());
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/guest_user_view.h b/chrome/browser/chromeos/login/guest_user_view.h
new file mode 100644
index 0000000..d9590f5
--- /dev/null
+++ b/chrome/browser/chromeos/login/guest_user_view.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_GUEST_USER_VIEW_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_GUEST_USER_VIEW_H_
+#pragma once
+
+#include "views/accelerator.h"
+#include "views/controls/button/native_button.h"
+#include "views/controls/textfield/textfield.h"
+#include "views/view.h"
+
+namespace chromeos {
+
+class UserController;
+
+// This view is for controls window of Guest mode pod that allows user to
+// get temporary profile and use it for browsing. Contains only one Sign-in
+// button and handles different common keyboard shortcuts.
+class GuestUserView : public views::View {
+ public:
+  explicit GuestUserView(UserController* uc);
+
+  void RecreateFields();
+
+  void FocusSignInButton();
+
+  // Overridden from views::View:
+  virtual bool AcceleratorPressed(const views::Accelerator& accelerator);
+
+ private:
+  // Overridden from views::View:
+  virtual void OnLocaleChanged();
+  virtual void ViewHierarchyChanged(bool is_add,
+                                    views::View* parent,
+                                    views::View* child);
+  virtual void Layout();
+
+  // Button to start login.
+  views::NativeButton* submit_button_;
+
+  UserController* user_controller_;
+
+  views::Accelerator accel_enable_accessibility_;
+  views::Accelerator accel_login_off_the_record_;
+  views::Accelerator accel_previous_pod_by_arrow_;
+  views::Accelerator accel_previous_pod_by_tab_;
+  views::Accelerator accel_next_pod_by_arrow_;
+  views::Accelerator accel_next_pod_by_tab_;
+
+  DISALLOW_COPY_AND_ASSIGN(GuestUserView);
+};
+
+}  // chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_GUEST_USER_VIEW_H_
diff --git a/chrome/browser/chromeos/login/user_controller.cc b/chrome/browser/chromeos/login/user_controller.cc
index c005270fd..64b6b53d 100644
--- a/chrome/browser/chromeos/login/user_controller.cc
+++ b/chrome/browser/chromeos/login/user_controller.cc
@@ -12,6 +12,7 @@
 #include "base/stringprintf.h"
 #include "base/utf_string_conversions.h"
 #include "chrome/browser/chromeos/login/existing_user_view.h"
+#include "chrome/browser/chromeos/login/guest_user_view.h"
 #include "chrome/browser/chromeos/login/helper.h"
 #include "chrome/browser/chromeos/login/rounded_rect_painter.h"
 #include "chrome/browser/chromeos/login/user_view.h"
@@ -58,7 +59,7 @@
  private:
   gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event) {
     if (!controller_->is_user_selected())
-      controller_->SelectUser(controller_->user_index(), true);
+      controller_->SelectUser(controller_->user_index());
 
     return views::WidgetGtk::OnButtonPress(widget, event);
   }
@@ -96,6 +97,7 @@
       user_view_(NULL),
       new_user_view_(NULL),
       existing_user_view_(NULL),
+      guest_user_view_(NULL),
       label_view_(NULL),
       unselected_label_view_(NULL) {
   registrar_.Add(
@@ -121,6 +123,7 @@
       user_view_(NULL),
       new_user_view_(NULL),
       existing_user_view_(NULL),
+      guest_user_view_(NULL),
       label_view_(NULL),
       unselected_label_view_(NULL) {
   registrar_.Add(
@@ -188,6 +191,7 @@
 
 void UserController::ClearAndEnablePassword() {
   if (is_new_user_) {
+    // TODO(avayvod): This code seems not reachable to me.
     new_user_view_->ClearAndEnablePassword();
   } else {
     existing_user_view_->password_field()->SetText(string16());
@@ -199,6 +203,8 @@
 void UserController::ClearAndEnableFields() {
   if (is_new_user_) {
     new_user_view_->ClearAndEnableFields();
+  } else if (is_bwsi_) {
+    guest_user_view_->FocusSignInButton();
   } else {
     ClearAndEnablePassword();
   }
@@ -229,10 +235,10 @@
     Login();
     return true;
   } else if (keystroke.GetKeyboardCode() == app::VKEY_LEFT) {
-    SelectUser(user_index() - 1, false);
+    SelectUser(user_index() - 1);
     return true;
   } else if (keystroke.GetKeyboardCode() == app::VKEY_RIGHT) {
-    SelectUser(user_index() + 1, false);
+    SelectUser(user_index() + 1);
     return true;
   }
   delegate_->ClearErrors();
@@ -335,6 +341,10 @@
         new NewUserView(this, false, need_browse_without_signin);
     new_user_view_->Init();
     control_view = new_user_view_;
+  } else if (is_bwsi_) {
+    guest_user_view_ = new GuestUserView(this);
+    guest_user_view_->RecreateFields();
+    control_view = guest_user_view_;
   } else {
     existing_user_view_ = new ExistingUserView(this);
     existing_user_view_->RecreateFields();
@@ -344,8 +354,6 @@
   *height = kControlsHeight;
   if (is_new_user_)
     *height += kUserImageSize + kUserNameGap;
-  if (is_bwsi_)
-    *height = 1;
 
   WidgetGtk* window = new WidgetGtk(WidgetGtk::TYPE_WINDOW);
   ConfigureLoginWindow(window,
@@ -388,8 +396,6 @@
   int height = kBorderSize * 2 + controls_height;
   if (!is_new_user_)
     height += kBorderSize + kUserImageSize;
-  if (is_bwsi_)
-    height = kBorderSize * 2 + kUserImageSize + 1;
   border_window_ = new WidgetGtk(WidgetGtk::TYPE_WINDOW);
   border_window_->MakeTransparent();
   border_window_->Init(NULL, gfx::Rect(0, 0, width, height));
@@ -484,18 +490,15 @@
 }
 
 void UserController::NavigateAway() {
-  SelectUser(user_index() - 1, false);
+  SelectUser(user_index() - 1);
 }
 
 void UserController::OnRemoveUser() {
   delegate_->RemoveUser(this);
 }
 
-void UserController::SelectUser(int index, bool is_click) {
-  if (is_click && is_bwsi_)
-    delegate_->LoginOffTheRecord();
-  else
-    delegate_->SelectUser(index);
+void UserController::SelectUser(int index) {
+  delegate_->SelectUser(index);
 }
 
 void UserController::FocusPasswordField() {
diff --git a/chrome/browser/chromeos/login/user_controller.h b/chrome/browser/chromeos/login/user_controller.h
index c62e94c9..4421f69f3 100644
--- a/chrome/browser/chromeos/login/user_controller.h
+++ b/chrome/browser/chromeos/login/user_controller.h
@@ -26,8 +26,9 @@
 
 namespace chromeos {
 
-class UserView;
 class ExistingUserView;
+class GuestUserView;
+class UserView;
 
 // UserController manages the set of windows needed to login a single existing
 // user or first time login for a new user. ExistingUserController creates
@@ -131,9 +132,8 @@
   // UserView::Delegate implementation:
   virtual void OnRemoveUser();
 
-  // Selects user entry with specified |index|, |is_click| is true if the entry
-  // was selected by mouse click.
-  void SelectUser(int index, bool is_click);
+  // Selects user entry with specified |index|.
+  void SelectUser(int index);
 
   // Sets focus on password field.
   void FocusPasswordField();
@@ -214,6 +214,9 @@
   // View that is used for existing user login.
   ExistingUserView* existing_user_view_;
 
+  // View that is used for guest user login.
+  GuestUserView* guest_user_view_;
+
   // Views that show display name of the user.
   views::Label* label_view_;
   views::Label* unselected_label_view_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index a841567b..3ccef48 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -532,6 +532,8 @@
         'browser/chromeos/login/existing_user_view.h',
         'browser/chromeos/login/google_authenticator.cc',
         'browser/chromeos/login/google_authenticator.h',
+        'browser/chromeos/login/guest_user_view.cc',
+        'browser/chromeos/login/guest_user_view.h',
         'browser/chromeos/login/help_app_launcher.cc',
         'browser/chromeos/login/help_app_launcher.h',
         'browser/chromeos/login/helper.cc',