Home | History | Annotate | Download | only in login
      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_image_view.h"
      6 
      7 #include "base/utf_string_conversions.h"
      8 #include "chrome/browser/chromeos/login/default_images_view.h"
      9 #include "chrome/browser/chromeos/login/default_user_images.h"
     10 #include "chrome/browser/chromeos/login/helper.h"
     11 #include "chrome/browser/chromeos/login/rounded_rect_painter.h"
     12 #include "chrome/browser/chromeos/login/user_manager.h"
     13 #include "grit/generated_resources.h"
     14 #include "grit/theme_resources.h"
     15 #include "ui/base/l10n/l10n_util.h"
     16 #include "ui/base/resource/resource_bundle.h"
     17 #include "ui/gfx/canvas.h"
     18 #include "views/background.h"
     19 #include "views/controls/button/native_button.h"
     20 #include "views/controls/label.h"
     21 #include "views/layout/grid_layout.h"
     22 
     23 namespace {
     24 
     25 // Margin in pixels from the left and right borders of screen's contents.
     26 const int kHorizontalMargin = 10;
     27 // Margin in pixels from the top and bottom borders of screen's contents.
     28 const int kVerticalMargin = 10;
     29 // Padding between horizontally neighboring elements.
     30 const int kHorizontalPadding = 10;
     31 // Padding between vertically neighboring elements.
     32 const int kVerticalPadding = 10;
     33 // Color for splitter separating contents from OK button.
     34 const SkColor kSplitterColor = SkColorSetRGB(187, 195, 200);
     35 // Height for the splitter.
     36 const int kSplitterHeight = 1;
     37 
     38 // IDs of column sets for grid layout manager.
     39 enum ColumnSets {
     40   kTitleRow,     // Column set for screen title.
     41   kImagesRow,    // Column set for image from camera and snapshot button.
     42   kSplitterRow, // Place for the splitter.
     43   kButtonsRow,   // Column set for OK button.
     44 };
     45 
     46 views::View* CreateSplitter(const SkColor& color) {
     47   views::View* splitter = new views::View();
     48   splitter->set_background(views::Background::CreateSolidBackground(color));
     49   return splitter;
     50 }
     51 
     52 }  // namespace
     53 
     54 namespace chromeos {
     55 
     56 UserImageView::UserImageView(Delegate* delegate)
     57     : title_label_(NULL),
     58       default_images_view_(NULL),
     59       take_photo_view_(NULL),
     60       splitter_(NULL),
     61       ok_button_(NULL),
     62       delegate_(delegate) {
     63 }
     64 
     65 UserImageView::~UserImageView() {
     66 }
     67 
     68 void UserImageView::Init() {
     69   // Use rounded rect background.
     70   set_border(CreateWizardBorder(&BorderDefinition::kScreenBorder));
     71   views::Painter* painter = CreateWizardPainter(
     72       &BorderDefinition::kScreenBorder);
     73   set_background(views::Background::CreateBackgroundPainter(true, painter));
     74 
     75   title_label_ = new views::Label(UTF16ToWide(
     76       l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT)));
     77   title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
     78   title_label_->SetMultiLine(true);
     79   CorrectLabelFontSize(title_label_);
     80 
     81   default_images_view_ = new DefaultImagesView(this);
     82   take_photo_view_ = new TakePhotoView(this);
     83   take_photo_view_->set_show_title(false);
     84 
     85   splitter_ = CreateSplitter(kSplitterColor);
     86 
     87   ok_button_ = new login::WideButton(
     88       this, UTF16ToWide(l10n_util::GetStringUTF16(IDS_OK)));
     89   ok_button_->SetEnabled(false);
     90 
     91   InitLayout();
     92 
     93   default_images_view_->Init();
     94   take_photo_view_->Init();
     95 
     96   UserManager* user_manager = UserManager::Get();
     97   const std::string& logged_in_user = user_manager->logged_in_user().email();
     98   int image_index = user_manager->GetUserDefaultImageIndex(logged_in_user);
     99 
    100   default_images_view_->SetDefaultImageIndex(image_index);
    101 }
    102 
    103 void UserImageView::InitLayout() {
    104   views::GridLayout* layout = new views::GridLayout(this);
    105   layout->SetInsets(GetInsets());
    106   SetLayoutManager(layout);
    107 
    108   // The title, left-top aligned.
    109   views::ColumnSet* column_set = layout->AddColumnSet(kTitleRow);
    110   column_set->AddPaddingColumn(0, kHorizontalMargin);
    111   column_set->AddColumn(views::GridLayout::FILL,
    112                         views::GridLayout::LEADING,
    113                         1,
    114                         views::GridLayout::USE_PREF, 0, 0);
    115   column_set->AddPaddingColumn(0, kHorizontalMargin);
    116 
    117   // The view with default images and the one with image from camera and label.
    118   column_set = layout->AddColumnSet(kImagesRow);
    119   column_set->AddPaddingColumn(0, kHorizontalMargin);
    120   column_set->AddColumn(views::GridLayout::LEADING,
    121                         views::GridLayout::LEADING,
    122                         0,
    123                         views::GridLayout::USE_PREF, 0, 0);
    124   column_set->AddPaddingColumn(0, kHorizontalPadding);
    125   column_set->AddColumn(views::GridLayout::FILL,
    126                         views::GridLayout::LEADING,
    127                         1,
    128                         views::GridLayout::USE_PREF, 0, 0);
    129   column_set->AddPaddingColumn(0, kHorizontalMargin);
    130 
    131   // Splitter.
    132   column_set = layout->AddColumnSet(kSplitterRow);
    133   column_set->AddColumn(views::GridLayout::FILL,
    134                         views::GridLayout::TRAILING,
    135                         1,
    136                         views::GridLayout::USE_PREF, 0, 0);
    137 
    138   // OK button is in the right bottom corner of the view.
    139   column_set = layout->AddColumnSet(kButtonsRow);
    140   column_set->AddPaddingColumn(0, kHorizontalMargin);
    141   column_set->AddColumn(views::GridLayout::TRAILING,
    142                         views::GridLayout::TRAILING,
    143                         1,
    144                         views::GridLayout::USE_PREF, 0, 0);
    145   column_set->AddPaddingColumn(0, kHorizontalMargin);
    146 
    147   // Fill the layout with rows and views now.
    148   layout->StartRowWithPadding(0, kTitleRow, 0, kVerticalMargin);
    149   layout->AddView(title_label_);
    150   layout->StartRowWithPadding(0, kImagesRow, 0, kVerticalPadding);
    151   layout->AddView(default_images_view_);
    152   layout->AddView(take_photo_view_);
    153   layout->StartRowWithPadding(1, kSplitterRow, 0, kVerticalPadding);
    154   // Set height for splitter view explicitly otherwise it's set to 0
    155   // by default.
    156   layout->AddView(splitter_,
    157                   1, 1,
    158                   views::GridLayout::FILL,
    159                   views::GridLayout::TRAILING,
    160                   0,
    161                   kSplitterHeight);
    162   layout->StartRowWithPadding(0, kButtonsRow, 0, kVerticalPadding);
    163   layout->AddView(ok_button_);
    164   layout->AddPaddingRow(0, kVerticalMargin);
    165 }
    166 
    167 void UserImageView::UpdateVideoFrame(const SkBitmap& frame) {
    168   DCHECK(take_photo_view_);
    169   take_photo_view_->UpdateVideoFrame(frame);
    170 }
    171 
    172 void UserImageView::ShowCameraInitializing() {
    173   DCHECK(take_photo_view_);
    174   take_photo_view_->ShowCameraInitializing();
    175 }
    176 
    177 void UserImageView::ShowCameraError() {
    178   DCHECK(take_photo_view_);
    179   take_photo_view_->ShowCameraError();
    180 }
    181 
    182 bool UserImageView::IsCapturing() const {
    183   DCHECK(default_images_view_);
    184   DCHECK(take_photo_view_);
    185   return default_images_view_->GetDefaultImageIndex() == -1 &&
    186          take_photo_view_->is_capturing();
    187 }
    188 
    189 gfx::Size UserImageView::GetPreferredSize() {
    190   return gfx::Size(width(), height());
    191 }
    192 
    193 void UserImageView::ButtonPressed(
    194     views::Button* sender, const views::Event& event) {
    195   DCHECK(delegate_);
    196   if (sender == ok_button_) {
    197     if (default_images_view_->GetDefaultImageIndex() == -1) {
    198       delegate_->OnPhotoTaken(take_photo_view_->GetImage());
    199     } else {
    200       delegate_->OnDefaultImageSelected(
    201           default_images_view_->GetDefaultImageIndex());
    202     }
    203   } else {
    204     NOTREACHED();
    205   }
    206 }
    207 
    208 void UserImageView::OnCapturingStarted() {
    209   delegate_->StartCamera();
    210   default_images_view_->ClearSelection();
    211   ok_button_->SetEnabled(false);
    212   ShowCameraInitializing();
    213 }
    214 
    215 void UserImageView::OnCapturingStopped() {
    216   delegate_->StopCamera();
    217   default_images_view_->ClearSelection();
    218   ok_button_->SetEnabled(true);
    219   ok_button_->RequestFocus();
    220 }
    221 
    222 void UserImageView::OnCaptureButtonClicked() {
    223   if (!IsCapturing())
    224     OnCapturingStarted();
    225 }
    226 
    227 void UserImageView::OnImageSelected(int image_index) {
    228   // Can happen when user is not known, i.e. in tests.
    229   if (image_index < 0 || image_index >= kDefaultImagesCount)
    230     return;
    231   delegate_->StopCamera();
    232   ok_button_->SetEnabled(true);
    233   ok_button_->RequestFocus();
    234   take_photo_view_->SetImage(
    235       ResourceBundle::GetSharedInstance().GetBitmapNamed(
    236             kDefaultImageResources[image_index]));
    237 }
    238 
    239 }  // namespace chromeos
    240