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