user_image_view.cc revision 513209b27ff55e2841eac0e4120199c23acce758
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_image_view.h" 6 7#include <algorithm> 8 9#include "app/l10n_util.h" 10#include "app/resource_bundle.h" 11#include "base/callback.h" 12#include "chrome/browser/chromeos/login/helper.h" 13#include "chrome/browser/chromeos/login/rounded_rect_painter.h" 14#include "chrome/browser/chromeos/login/wizard_accessibility_helper.h" 15#include "chrome/browser/profile_manager.h" 16#include "gfx/canvas.h" 17#include "grit/generated_resources.h" 18#include "grit/theme_resources.h" 19#include "skia/ext/image_operations.h" 20#include "views/controls/button/image_button.h" 21#include "views/controls/button/native_button.h" 22#include "views/controls/image_view.h" 23#include "views/controls/label.h" 24#include "views/grid_layout.h" 25 26namespace { 27 28// Margin in pixels from the left and right borders of screen's contents. 29const int kHorizontalMargin = 10; 30// Margin in pixels from the top and bottom borders of screen's contents. 31const int kVerticalMargin = 10; 32// Padding between horizontally neighboring elements. 33const int kHorizontalPadding = 10; 34// Padding between vertically neighboring elements. 35const int kVerticalPadding = 10; 36 37// IDs of column sets for grid layout manager. 38enum ColumnSets { 39 kTitleRow, // Column set for screen title. 40 kImageRow, // Column set for image from camera and snapshot button. 41 kButtonsRow, // Column set for Skip and OK buttons. 42}; 43 44} // namespace 45 46namespace chromeos { 47 48using login::kUserImageSize; 49 50UserImageView::UserImageView(Delegate* delegate) 51 : title_label_(NULL), 52 ok_button_(NULL), 53 skip_button_(NULL), 54 snapshot_button_(NULL), 55 user_image_(NULL), 56 delegate_(delegate), 57 is_capturing_(true) { 58} 59 60UserImageView::~UserImageView() { 61} 62 63void UserImageView::Init() { 64 // Use rounded rect background. 65 set_border(CreateWizardBorder(&BorderDefinition::kScreenBorder)); 66 views::Painter* painter = CreateWizardPainter( 67 &BorderDefinition::kScreenBorder); 68 set_background(views::Background::CreateBackgroundPainter(true, painter)); 69 70 title_label_ = 71 new views::Label(l10n_util::GetString(IDS_USER_IMAGE_SCREEN_TITLE)); 72 title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 73 title_label_->SetMultiLine(true); 74 75 user_image_ = new views::ImageView(); 76 user_image_->SetImageSize( 77 gfx::Size(kUserImageSize, kUserImageSize)); 78 user_image_->SetImage( 79 ResourceBundle::GetSharedInstance().GetBitmapNamed( 80 IDR_USER_IMAGE_NO_VIDEO)); 81 82 snapshot_button_ = new views::ImageButton(this); 83 snapshot_button_->SetFocusable(true); 84 snapshot_button_->SetImage(views::CustomButton::BS_NORMAL, 85 ResourceBundle::GetSharedInstance().GetBitmapNamed( 86 IDR_USER_IMAGE_CAPTURE)); 87 88 ok_button_ = new views::NativeButton(this, l10n_util::GetString(IDS_OK)); 89 ok_button_->SetEnabled(!is_capturing_); 90 91 skip_button_ = new views::NativeButton(this, l10n_util::GetString(IDS_SKIP)); 92 skip_button_->SetEnabled(true); 93 94 InitLayout(); 95 // Request focus only after the button is added to views hierarchy. 96 snapshot_button_->RequestFocus(); 97} 98 99void UserImageView::InitLayout() { 100 views::GridLayout* layout = new views::GridLayout(this); 101 layout->SetInsets(GetInsets()); 102 SetLayoutManager(layout); 103 104 // The title is left-top aligned. 105 views::ColumnSet* column_set = layout->AddColumnSet(kTitleRow); 106 column_set->AddPaddingColumn(0, kHorizontalMargin); 107 column_set->AddColumn(views::GridLayout::LEADING, 108 views::GridLayout::LEADING, 109 1, 110 views::GridLayout::USE_PREF, 0, 0); 111 column_set->AddPaddingColumn(0, kHorizontalMargin); 112 113 // User image and snapshot button are centered horizontally. 114 column_set = layout->AddColumnSet(kImageRow); 115 column_set->AddPaddingColumn(0, kHorizontalMargin); 116 column_set->AddColumn(views::GridLayout::CENTER, 117 views::GridLayout::LEADING, 118 1, 119 views::GridLayout::USE_PREF, 0, 0); 120 column_set->AddPaddingColumn(0, kHorizontalMargin); 121 122 // OK and Skip buttons are in the right bottom corner of the view. 123 column_set = layout->AddColumnSet(kButtonsRow); 124 column_set->AddPaddingColumn(0, kHorizontalMargin); 125 // This column takes the empty space to the left of the buttons. 126 column_set->AddPaddingColumn(1, 1); 127 column_set->AddColumn(views::GridLayout::TRAILING, 128 views::GridLayout::TRAILING, 129 0, 130 views::GridLayout::USE_PREF, 0, 0); 131 column_set->AddPaddingColumn(0, kHorizontalPadding); 132 column_set->AddColumn(views::GridLayout::TRAILING, 133 views::GridLayout::TRAILING, 134 0, 135 views::GridLayout::USE_PREF, 0, 0); 136 column_set->AddPaddingColumn(0, kHorizontalMargin); 137 138 // Fill the layout with rows and views now. 139 layout->StartRowWithPadding(0, kTitleRow, 0, kVerticalMargin); 140 layout->AddView(title_label_); 141 layout->StartRowWithPadding(0, kImageRow, 0, kVerticalPadding); 142 layout->AddView(user_image_); 143 layout->StartRowWithPadding(1, kImageRow, 0, kVerticalPadding); 144 layout->AddView(snapshot_button_); 145 layout->StartRowWithPadding(0, kButtonsRow, 0, kVerticalPadding); 146 layout->AddView(skip_button_); 147 layout->AddView(ok_button_); 148 layout->AddPaddingRow(0, kVerticalMargin); 149} 150 151void UserImageView::UpdateVideoFrame(const SkBitmap& frame) { 152 if (!is_capturing_) 153 return; 154 155 if (!snapshot_button_->IsEnabled()) { 156 snapshot_button_->SetEnabled(true); 157 snapshot_button_->RequestFocus(); 158 } 159 SkBitmap user_image = 160 skia::ImageOperations::Resize( 161 frame, 162 skia::ImageOperations::RESIZE_BOX, 163 kUserImageSize, 164 kUserImageSize); 165 166 user_image_->SetImage(&user_image); 167} 168 169void UserImageView::ShowCameraError() { 170 if (!is_capturing_ || !snapshot_button_->IsEnabled()) 171 return; 172 snapshot_button_->SetEnabled(false); 173 user_image_->SetImage( 174 ResourceBundle::GetSharedInstance().GetBitmapNamed( 175 IDR_USER_IMAGE_NO_VIDEO)); 176} 177 178void UserImageView::ViewHierarchyChanged(bool is_add, 179 views::View* parent, 180 views::View* child) { 181 if (is_add && this == child) 182 WizardAccessibilityHelper::GetInstance()->MaybeEnableAccessibility(this); 183} 184 185gfx::Size UserImageView::GetPreferredSize() { 186 return gfx::Size(width(), height()); 187} 188 189void UserImageView::ButtonPressed( 190 views::Button* sender, const views::Event& event) { 191 DCHECK(delegate_); 192 if (sender == snapshot_button_) { 193 if (is_capturing_) { 194 ok_button_->SetEnabled(true); 195 ok_button_->RequestFocus(); 196 snapshot_button_->SetImage( 197 views::CustomButton::BS_NORMAL, 198 ResourceBundle::GetSharedInstance().GetBitmapNamed( 199 IDR_USER_IMAGE_RECYCLE)); 200 } else { 201 ok_button_->SetEnabled(false); 202 snapshot_button_->SetImage( 203 views::CustomButton::BS_NORMAL, 204 ResourceBundle::GetSharedInstance().GetBitmapNamed( 205 IDR_USER_IMAGE_CAPTURE)); 206 } 207 snapshot_button_->SchedulePaint(); 208 is_capturing_ = !is_capturing_; 209 } else if (sender == ok_button_) { 210 delegate_->OnOK(user_image_->GetImage()); 211 } else if (sender == skip_button_) { 212 delegate_->OnSkip(); 213 } else { 214 NOTREACHED(); 215 } 216} 217 218} // namespace chromeos 219 220