| OLD | NEW |
| (Empty) |
| 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 <string> | |
| 8 | |
| 9 #include "base/utf_string_conversions.h" | |
| 10 #include "chrome/browser/browser_process.h" | |
| 11 #include "chrome/browser/chromeos/login/default_images_view.h" | |
| 12 #include "chrome/browser/chromeos/login/default_user_images.h" | |
| 13 #include "chrome/browser/chromeos/login/helper.h" | |
| 14 #include "chrome/browser/chromeos/login/rounded_rect_painter.h" | |
| 15 #include "chrome/browser/chromeos/login/user_manager.h" | |
| 16 #include "chrome/browser/policy/browser_policy_connector.h" | |
| 17 #include "grit/generated_resources.h" | |
| 18 #include "grit/theme_resources.h" | |
| 19 #include "ui/base/l10n/l10n_util.h" | |
| 20 #include "ui/base/resource/resource_bundle.h" | |
| 21 #include "ui/gfx/canvas.h" | |
| 22 #include "views/background.h" | |
| 23 #include "views/controls/button/text_button.h" | |
| 24 #include "views/controls/label.h" | |
| 25 #include "views/layout/grid_layout.h" | |
| 26 | |
| 27 namespace { | |
| 28 | |
| 29 // The delay of triggering initialization of the user policy subsystem | |
| 30 // after the user image selection screen is initialized. This makes sure that | |
| 31 // user policy network requests are made while the system is idle waiting for | |
| 32 // user input. | |
| 33 const int64 kPolicyServiceInitializationDelayMilliseconds = 400; | |
| 34 | |
| 35 // Margin in pixels from the left and right borders of screen's contents. | |
| 36 const int kHorizontalMargin = 10; | |
| 37 // Margin in pixels from the top and bottom borders of screen's contents. | |
| 38 const int kVerticalMargin = 10; | |
| 39 // Padding between horizontally neighboring elements. | |
| 40 const int kHorizontalPadding = 10; | |
| 41 // Padding between vertically neighboring elements. | |
| 42 const int kVerticalPadding = 10; | |
| 43 // Color for splitter separating contents from OK button. | |
| 44 const SkColor kSplitterColor = SkColorSetRGB(187, 195, 200); | |
| 45 // Height for the splitter. | |
| 46 const int kSplitterHeight = 1; | |
| 47 | |
| 48 // IDs of column sets for grid layout manager. | |
| 49 enum ColumnSets { | |
| 50 kTitleRow, // Column set for screen title. | |
| 51 kImagesRow, // Column set for image from camera and snapshot button. | |
| 52 kSplitterRow, // Place for the splitter. | |
| 53 kButtonsRow, // Column set for OK button. | |
| 54 }; | |
| 55 | |
| 56 views::View* CreateSplitter(const SkColor& color) { | |
| 57 views::View* splitter = new views::View(); | |
| 58 splitter->set_background(views::Background::CreateSolidBackground(color)); | |
| 59 return splitter; | |
| 60 } | |
| 61 | |
| 62 } // namespace | |
| 63 | |
| 64 namespace chromeos { | |
| 65 | |
| 66 UserImageView::UserImageView(Delegate* delegate) | |
| 67 : title_label_(NULL), | |
| 68 default_images_view_(NULL), | |
| 69 take_photo_view_(NULL), | |
| 70 splitter_(NULL), | |
| 71 ok_button_(NULL), | |
| 72 delegate_(delegate) { | |
| 73 } | |
| 74 | |
| 75 UserImageView::~UserImageView() { | |
| 76 } | |
| 77 | |
| 78 void UserImageView::Init() { | |
| 79 // Use rounded rect background. | |
| 80 set_border(CreateWizardBorder(&BorderDefinition::kScreenBorder)); | |
| 81 views::Painter* painter = CreateWizardPainter( | |
| 82 &BorderDefinition::kScreenBorder); | |
| 83 set_background(views::Background::CreateBackgroundPainter(true, painter)); | |
| 84 | |
| 85 title_label_ = new views::Label( | |
| 86 l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT)); | |
| 87 title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
| 88 title_label_->SetMultiLine(true); | |
| 89 CorrectLabelFontSize(title_label_); | |
| 90 | |
| 91 default_images_view_ = new DefaultImagesView(this); | |
| 92 take_photo_view_ = new TakePhotoView(this); | |
| 93 take_photo_view_->set_show_title(false); | |
| 94 | |
| 95 splitter_ = CreateSplitter(kSplitterColor); | |
| 96 | |
| 97 ok_button_ = new login::WideButton(this, l10n_util::GetStringUTF16(IDS_OK)); | |
| 98 ok_button_->set_focusable(true); | |
| 99 ok_button_->SetEnabled(false); | |
| 100 | |
| 101 accel_ok_ = views::Accelerator(ui::VKEY_RETURN, false, false, false); | |
| 102 accel_up_ = views::Accelerator(ui::VKEY_UP, false, false, false); | |
| 103 accel_down_ = views::Accelerator(ui::VKEY_DOWN, false, false, false); | |
| 104 accel_left_ = views::Accelerator(ui::VKEY_LEFT, false, false, false); | |
| 105 accel_right_ = views::Accelerator(ui::VKEY_RIGHT, false, false, false); | |
| 106 | |
| 107 AddAccelerator(accel_ok_); | |
| 108 AddAccelerator(accel_up_); | |
| 109 AddAccelerator(accel_down_); | |
| 110 AddAccelerator(accel_left_); | |
| 111 AddAccelerator(accel_right_); | |
| 112 | |
| 113 InitLayout(); | |
| 114 | |
| 115 default_images_view_->Init(); | |
| 116 take_photo_view_->Init(); | |
| 117 | |
| 118 UserManager* user_manager = UserManager::Get(); | |
| 119 const std::string& logged_in_user = user_manager->logged_in_user().email(); | |
| 120 int image_index = user_manager->GetUserDefaultImageIndex(logged_in_user); | |
| 121 | |
| 122 default_images_view_->SetDefaultImageIndex(image_index); | |
| 123 | |
| 124 // Notify the policy subsystem that the system is idle enough now for a | |
| 125 // policy fetch. (The policy fetch will happen after some delay, see | |
| 126 // implementation.) | |
| 127 g_browser_process->browser_policy_connector()->ScheduleServiceInitialization( | |
| 128 kPolicyServiceInitializationDelayMilliseconds); | |
| 129 } | |
| 130 | |
| 131 void UserImageView::InitLayout() { | |
| 132 views::GridLayout* layout = new views::GridLayout(this); | |
| 133 layout->SetInsets(GetInsets()); | |
| 134 SetLayoutManager(layout); | |
| 135 | |
| 136 // The title, left-top aligned. | |
| 137 views::ColumnSet* column_set = layout->AddColumnSet(kTitleRow); | |
| 138 column_set->AddPaddingColumn(0, kHorizontalMargin); | |
| 139 column_set->AddColumn(views::GridLayout::FILL, | |
| 140 views::GridLayout::LEADING, | |
| 141 1, | |
| 142 views::GridLayout::USE_PREF, 0, 0); | |
| 143 column_set->AddPaddingColumn(0, kHorizontalMargin); | |
| 144 | |
| 145 // The view with default images and the one with image from camera and label. | |
| 146 column_set = layout->AddColumnSet(kImagesRow); | |
| 147 column_set->AddPaddingColumn(0, kHorizontalMargin); | |
| 148 column_set->AddColumn(views::GridLayout::LEADING, | |
| 149 views::GridLayout::LEADING, | |
| 150 0, | |
| 151 views::GridLayout::USE_PREF, 0, 0); | |
| 152 column_set->AddPaddingColumn(0, kHorizontalPadding); | |
| 153 column_set->AddColumn(views::GridLayout::FILL, | |
| 154 views::GridLayout::LEADING, | |
| 155 1, | |
| 156 views::GridLayout::USE_PREF, 0, 0); | |
| 157 column_set->AddPaddingColumn(0, kHorizontalMargin); | |
| 158 | |
| 159 // Splitter. | |
| 160 column_set = layout->AddColumnSet(kSplitterRow); | |
| 161 column_set->AddColumn(views::GridLayout::FILL, | |
| 162 views::GridLayout::TRAILING, | |
| 163 1, | |
| 164 views::GridLayout::USE_PREF, 0, 0); | |
| 165 | |
| 166 // OK button is in the right bottom corner of the view. | |
| 167 column_set = layout->AddColumnSet(kButtonsRow); | |
| 168 column_set->AddPaddingColumn(0, kHorizontalMargin); | |
| 169 column_set->AddColumn(views::GridLayout::TRAILING, | |
| 170 views::GridLayout::TRAILING, | |
| 171 1, | |
| 172 views::GridLayout::USE_PREF, 0, 0); | |
| 173 column_set->AddPaddingColumn(0, kHorizontalMargin); | |
| 174 | |
| 175 // Fill the layout with rows and views now. | |
| 176 layout->StartRowWithPadding(0, kTitleRow, 0, kVerticalMargin); | |
| 177 layout->AddView(title_label_); | |
| 178 layout->StartRowWithPadding(0, kImagesRow, 0, kVerticalPadding); | |
| 179 layout->AddView(default_images_view_); | |
| 180 layout->AddView(take_photo_view_); | |
| 181 layout->StartRowWithPadding(1, kSplitterRow, 0, kVerticalPadding); | |
| 182 // Set height for splitter view explicitly otherwise it's set to 0 | |
| 183 // by default. | |
| 184 layout->AddView(splitter_, | |
| 185 1, 1, | |
| 186 views::GridLayout::FILL, | |
| 187 views::GridLayout::TRAILING, | |
| 188 0, | |
| 189 kSplitterHeight); | |
| 190 layout->StartRowWithPadding(0, kButtonsRow, 0, kVerticalPadding); | |
| 191 layout->AddView(ok_button_); | |
| 192 layout->AddPaddingRow(0, kVerticalMargin); | |
| 193 } | |
| 194 | |
| 195 void UserImageView::UpdateVideoFrame(const SkBitmap& frame) { | |
| 196 DCHECK(take_photo_view_); | |
| 197 take_photo_view_->UpdateVideoFrame(frame); | |
| 198 } | |
| 199 | |
| 200 void UserImageView::ShowCameraInitializing() { | |
| 201 DCHECK(take_photo_view_); | |
| 202 take_photo_view_->ShowCameraInitializing(); | |
| 203 } | |
| 204 | |
| 205 void UserImageView::ShowCameraError() { | |
| 206 DCHECK(take_photo_view_); | |
| 207 take_photo_view_->ShowCameraError(); | |
| 208 } | |
| 209 | |
| 210 bool UserImageView::IsCapturing() const { | |
| 211 DCHECK(default_images_view_); | |
| 212 DCHECK(take_photo_view_); | |
| 213 return default_images_view_->GetDefaultImageIndex() == -1 && | |
| 214 take_photo_view_->is_capturing(); | |
| 215 } | |
| 216 | |
| 217 gfx::Size UserImageView::GetPreferredSize() { | |
| 218 return gfx::Size(width(), height()); | |
| 219 } | |
| 220 | |
| 221 void UserImageView::NotifyDelegateOfImageSelected() { | |
| 222 DCHECK(delegate_); | |
| 223 DCHECK(default_images_view_); | |
| 224 DCHECK(take_photo_view_); | |
| 225 if (default_images_view_->GetDefaultImageIndex() == -1) { | |
| 226 delegate_->OnPhotoTaken(take_photo_view_->GetImage()); | |
| 227 } else { | |
| 228 delegate_->OnDefaultImageSelected( | |
| 229 default_images_view_->GetDefaultImageIndex()); | |
| 230 } | |
| 231 } | |
| 232 | |
| 233 void UserImageView::ButtonPressed( | |
| 234 views::Button* sender, const views::Event& event) { | |
| 235 DCHECK(delegate_); | |
| 236 if (sender == ok_button_) | |
| 237 NotifyDelegateOfImageSelected(); | |
| 238 else | |
| 239 NOTREACHED(); | |
| 240 } | |
| 241 | |
| 242 bool UserImageView::AcceleratorPressed(const views::Accelerator& accel) { | |
| 243 if (accel == accel_ok_) { | |
| 244 if (IsCapturing()) | |
| 245 take_photo_view_->CaptureImage(); | |
| 246 else | |
| 247 NotifyDelegateOfImageSelected(); | |
| 248 } else if (accel == accel_up_) { | |
| 249 default_images_view_->SelectPreviousRowImage(); | |
| 250 } else if (accel == accel_down_) { | |
| 251 default_images_view_->SelectNextRowImage(); | |
| 252 } else if (accel == accel_left_) { | |
| 253 default_images_view_->SelectPreviousImage(); | |
| 254 } else if (accel == accel_right_) { | |
| 255 default_images_view_->SelectNextImage(); | |
| 256 } else { | |
| 257 return false; | |
| 258 } | |
| 259 | |
| 260 return true; | |
| 261 } | |
| 262 | |
| 263 void UserImageView::OnCapturingStarted() { | |
| 264 delegate_->StartCamera(); | |
| 265 default_images_view_->ClearSelection(); | |
| 266 ok_button_->SetEnabled(false); | |
| 267 ShowCameraInitializing(); | |
| 268 } | |
| 269 | |
| 270 void UserImageView::OnCapturingStopped() { | |
| 271 delegate_->StopCamera(); | |
| 272 default_images_view_->ClearSelection(); | |
| 273 ok_button_->SetEnabled(true); | |
| 274 ok_button_->RequestFocus(); | |
| 275 } | |
| 276 | |
| 277 void UserImageView::OnCaptureButtonClicked() { | |
| 278 if (!IsCapturing()) | |
| 279 OnCapturingStarted(); | |
| 280 } | |
| 281 | |
| 282 void UserImageView::OnImageSelected(int image_index) { | |
| 283 // Can happen when user is not known, i.e. in tests. | |
| 284 if (image_index < 0 || image_index >= kDefaultImagesCount) | |
| 285 return; | |
| 286 delegate_->StopCamera(); | |
| 287 ok_button_->SetEnabled(true); | |
| 288 ok_button_->RequestFocus(); | |
| 289 take_photo_view_->SetImage( | |
| 290 ResourceBundle::GetSharedInstance().GetBitmapNamed( | |
| 291 kDefaultImageResources[image_index])); | |
| 292 } | |
| 293 | |
| 294 } // namespace chromeos | |
| OLD | NEW |