• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CreateSplitter(const SkColor & color)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 
UserImageView(Delegate * delegate)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 
~UserImageView()65 UserImageView::~UserImageView() {
66 }
67 
Init()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 
InitLayout()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 
UpdateVideoFrame(const SkBitmap & frame)167 void UserImageView::UpdateVideoFrame(const SkBitmap& frame) {
168   DCHECK(take_photo_view_);
169   take_photo_view_->UpdateVideoFrame(frame);
170 }
171 
ShowCameraInitializing()172 void UserImageView::ShowCameraInitializing() {
173   DCHECK(take_photo_view_);
174   take_photo_view_->ShowCameraInitializing();
175 }
176 
ShowCameraError()177 void UserImageView::ShowCameraError() {
178   DCHECK(take_photo_view_);
179   take_photo_view_->ShowCameraError();
180 }
181 
IsCapturing() const182 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 
GetPreferredSize()189 gfx::Size UserImageView::GetPreferredSize() {
190   return gfx::Size(width(), height());
191 }
192 
ButtonPressed(views::Button * sender,const views::Event & event)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 
OnCapturingStarted()208 void UserImageView::OnCapturingStarted() {
209   delegate_->StartCamera();
210   default_images_view_->ClearSelection();
211   ok_button_->SetEnabled(false);
212   ShowCameraInitializing();
213 }
214 
OnCapturingStopped()215 void UserImageView::OnCapturingStopped() {
216   delegate_->StopCamera();
217   default_images_view_->ClearSelection();
218   ok_button_->SetEnabled(true);
219   ok_button_->RequestFocus();
220 }
221 
OnCaptureButtonClicked()222 void UserImageView::OnCaptureButtonClicked() {
223   if (!IsCapturing())
224     OnCapturingStarted();
225 }
226 
OnImageSelected(int image_index)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