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