| 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/default_images_view.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/utf_string_conversions.h" | |
| 9 #include "chrome/browser/chromeos/login/default_user_images.h" | |
| 10 #include "chrome/browser/chromeos/login/rounded_rect_painter.h" | |
| 11 #include "grit/generated_resources.h" | |
| 12 #include "grit/theme_resources.h" | |
| 13 #include "skia/ext/image_operations.h" | |
| 14 #include "third_party/skia/include/core/SkColor.h" | |
| 15 #include "ui/base/l10n/l10n_util.h" | |
| 16 #include "ui/base/resource/resource_bundle.h" | |
| 17 #include "views/background.h" | |
| 18 #include "views/border.h" | |
| 19 #include "views/controls/button/image_button.h" | |
| 20 #include "views/layout/grid_layout.h" | |
| 21 | |
| 22 namespace chromeos { | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 // Size of the default image within the view. | |
| 27 const int kDefaultImageSize = 64; | |
| 28 // Margin from left and right sides to the view contents. | |
| 29 const int kHorizontalMargin = 10; | |
| 30 // Margin from top and bottom sides to the view contents. | |
| 31 const int kVerticalMargin = 10; | |
| 32 // Padding between image columns. | |
| 33 const int kHorizontalPadding = 20; | |
| 34 // Padding between image rows. | |
| 35 const int kVerticalPadding = 15; | |
| 36 // Number of columns in a row of default images. | |
| 37 const int kColumnsCount = 5; | |
| 38 // Size of the border around default image. | |
| 39 const int kImageBorderSize = 1; | |
| 40 // Color of default image border. | |
| 41 const SkColor kImageBorderColor = SkColorSetARGB(38, 0, 0, 0); | |
| 42 // Color of default image background. | |
| 43 const SkColor kImageBackgroundColor = SK_ColorWHITE; | |
| 44 // We give each image control an ID so we could distinguish them. Since 0 is | |
| 45 // the default ID we want an offset for IDs we set. | |
| 46 const int kImageStartId = 100; | |
| 47 // ID for image control for video capture. | |
| 48 const int kCaptureButtonId = 1000; | |
| 49 // Index of the item for video capture. | |
| 50 const int kCaptureButtonIndex = 0; | |
| 51 // A number of the first buttons that don't correspond to any default image | |
| 52 // (i.e. button to take a photo). | |
| 53 const int kNonDefaultImageButtonsCount = 1; | |
| 54 | |
| 55 } // namespace | |
| 56 | |
| 57 // Image button with border and background. Corrects view size by border | |
| 58 // insets as ImageButton ignores it. | |
| 59 class UserImageButton : public views::ImageButton { | |
| 60 public: | |
| 61 explicit UserImageButton(views::ButtonListener* listener); | |
| 62 | |
| 63 // Overridden from views::View: | |
| 64 virtual gfx::Size GetPreferredSize(); | |
| 65 | |
| 66 private: | |
| 67 DISALLOW_COPY_AND_ASSIGN(UserImageButton); | |
| 68 }; | |
| 69 | |
| 70 UserImageButton::UserImageButton(views::ButtonListener* listener) | |
| 71 : ImageButton(listener) { | |
| 72 set_border( | |
| 73 views::Border::CreateSolidBorder(kImageBorderSize, kImageBorderColor)); | |
| 74 set_background( | |
| 75 views::Background::CreateSolidBackground(kImageBackgroundColor)); | |
| 76 SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE); | |
| 77 } | |
| 78 | |
| 79 gfx::Size UserImageButton::GetPreferredSize() { | |
| 80 gfx::Size size = views::ImageButton::GetPreferredSize(); | |
| 81 size.Enlarge(GetInsets().width(), GetInsets().height()); | |
| 82 return size; | |
| 83 } | |
| 84 | |
| 85 | |
| 86 DefaultImagesView::DefaultImagesView(Delegate* delegate) | |
| 87 : selected_image_index_(-1), | |
| 88 delegate_(delegate) { | |
| 89 } | |
| 90 | |
| 91 DefaultImagesView::~DefaultImagesView() {} | |
| 92 | |
| 93 void DefaultImagesView::Init() { | |
| 94 UserImageButton* capture_button = new UserImageButton(this); | |
| 95 capture_button->set_id(kCaptureButtonId); | |
| 96 capture_button->SetTooltipText( | |
| 97 l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO)); | |
| 98 InitButton(IDR_BUTTON_USER_IMAGE_TAKE_PHOTO, capture_button); | |
| 99 default_images_.push_back(capture_button); | |
| 100 for (int i = 0; i < kDefaultImagesCount; ++i) { | |
| 101 UserImageButton* image_button = new UserImageButton(this); | |
| 102 image_button->set_id(i + kImageStartId); | |
| 103 InitButton(kDefaultImageResources[i], image_button); | |
| 104 default_images_.push_back(image_button); | |
| 105 } | |
| 106 InitLayout(); | |
| 107 } | |
| 108 | |
| 109 int DefaultImagesView::GetDefaultImageIndex() const { | |
| 110 if (selected_image_index_ == -1) | |
| 111 return -1; | |
| 112 else | |
| 113 return selected_image_index_ - kNonDefaultImageButtonsCount; | |
| 114 } | |
| 115 | |
| 116 void DefaultImagesView::SetDefaultImageIndex(int image_index) { | |
| 117 selected_image_index_ = image_index + kNonDefaultImageButtonsCount; | |
| 118 if (delegate_) | |
| 119 delegate_->OnImageSelected(image_index % kDefaultImagesCount); | |
| 120 } | |
| 121 | |
| 122 void DefaultImagesView::ClearSelection() { | |
| 123 selected_image_index_ = -1; | |
| 124 } | |
| 125 | |
| 126 void DefaultImagesView::SelectNextImage() { | |
| 127 // If there's no selection, start at 0. | |
| 128 if (selected_image_index_ < 0) | |
| 129 selected_image_index_ = 0; | |
| 130 | |
| 131 ++selected_image_index_; | |
| 132 if (selected_image_index_ >= kNonDefaultImageButtonsCount + | |
| 133 kDefaultImagesCount) { | |
| 134 selected_image_index_ = 0; | |
| 135 } | |
| 136 | |
| 137 UpdateSelectedImage(); | |
| 138 } | |
| 139 | |
| 140 void DefaultImagesView::SelectPreviousImage() { | |
| 141 // If there's no selection, start at 0. | |
| 142 if (selected_image_index_ < 0) | |
| 143 selected_image_index_ = 0; | |
| 144 | |
| 145 --selected_image_index_; | |
| 146 if (selected_image_index_ < 0) { | |
| 147 selected_image_index_ = kNonDefaultImageButtonsCount + | |
| 148 kDefaultImagesCount - 1; | |
| 149 } | |
| 150 | |
| 151 UpdateSelectedImage(); | |
| 152 } | |
| 153 | |
| 154 void DefaultImagesView::SelectNextRowImage() { | |
| 155 // If there's no selection, start at 0. | |
| 156 if (selected_image_index_ < 0) | |
| 157 selected_image_index_ = 0; | |
| 158 | |
| 159 selected_image_index_ += kColumnsCount; | |
| 160 if (selected_image_index_ >= kDefaultImagesCount + | |
| 161 kNonDefaultImageButtonsCount) { | |
| 162 selected_image_index_ -= kDefaultImagesCount + kNonDefaultImageButtonsCount; | |
| 163 } | |
| 164 | |
| 165 UpdateSelectedImage(); | |
| 166 } | |
| 167 | |
| 168 void DefaultImagesView::SelectPreviousRowImage() { | |
| 169 // If there's no selection, start at 0. | |
| 170 if (selected_image_index_ < 0) | |
| 171 selected_image_index_ = 0; | |
| 172 | |
| 173 selected_image_index_ -= kColumnsCount; | |
| 174 if (selected_image_index_ < 0) { | |
| 175 selected_image_index_ += kDefaultImagesCount + kNonDefaultImageButtonsCount; | |
| 176 } | |
| 177 | |
| 178 UpdateSelectedImage(); | |
| 179 } | |
| 180 | |
| 181 gfx::Size DefaultImagesView::GetPreferredSize() { | |
| 182 int image_size_with_margin = (kDefaultImageSize + 2 * kImageBorderSize); | |
| 183 int width = kColumnsCount * image_size_with_margin + | |
| 184 (kColumnsCount - 1) * kHorizontalPadding; | |
| 185 size_t image_count = default_images_.size(); | |
| 186 int rows_count = (image_count + kColumnsCount - 1) / kColumnsCount; | |
| 187 int height = rows_count * image_size_with_margin + | |
| 188 (rows_count - 1) * kVerticalPadding; | |
| 189 return gfx::Size(width + 2 * kHorizontalMargin, | |
| 190 height + 2 * kVerticalMargin); | |
| 191 } | |
| 192 | |
| 193 void DefaultImagesView::ButtonPressed(views::Button* sender, | |
| 194 const views::Event& event) { | |
| 195 if (selected_image_index_ != -1 && | |
| 196 default_images_[selected_image_index_] == sender) | |
| 197 return; | |
| 198 ClearSelection(); | |
| 199 | |
| 200 if (sender->id() == kCaptureButtonId) { | |
| 201 if (delegate_) | |
| 202 delegate_->OnCaptureButtonClicked(); | |
| 203 } else { | |
| 204 int image_index = sender->id() - kImageStartId; | |
| 205 int images_count = static_cast<int>(default_images_.size()); | |
| 206 if (image_index < 0 || image_index >= images_count) { | |
| 207 NOTREACHED() << "Got ButtonPressed event from a view with wrong id."; | |
| 208 return; | |
| 209 } | |
| 210 SetDefaultImageIndex(image_index); | |
| 211 } | |
| 212 } | |
| 213 | |
| 214 void DefaultImagesView::InitButton(int resource_id, | |
| 215 UserImageButton* button) const { | |
| 216 const SkBitmap* original_image = | |
| 217 ResourceBundle::GetSharedInstance().GetBitmapNamed(resource_id); | |
| 218 SkBitmap resized_image = skia::ImageOperations::Resize( | |
| 219 *original_image, | |
| 220 skia::ImageOperations::RESIZE_BEST, | |
| 221 kDefaultImageSize, kDefaultImageSize); | |
| 222 button->SetImage( | |
| 223 views::CustomButton::BS_NORMAL, | |
| 224 &resized_image); | |
| 225 } | |
| 226 | |
| 227 void DefaultImagesView::InitLayout() { | |
| 228 views::GridLayout* layout = new views::GridLayout(this); | |
| 229 layout->SetInsets(gfx::Insets(kVerticalMargin, | |
| 230 kHorizontalMargin, | |
| 231 kVerticalMargin, | |
| 232 kHorizontalMargin)); | |
| 233 SetLayoutManager(layout); | |
| 234 | |
| 235 size_t current_image = 0; | |
| 236 size_t image_count = default_images_.size(); | |
| 237 int rows_count = (image_count + kColumnsCount - 1) / kColumnsCount; | |
| 238 for (int row = 0; row < rows_count; ++row) { | |
| 239 views::ColumnSet* column_set = layout->AddColumnSet(row); | |
| 240 for (int column = 0; column < kColumnsCount; ++column) { | |
| 241 if (column != 0) | |
| 242 column_set->AddPaddingColumn(1, kHorizontalPadding); | |
| 243 if (current_image < image_count) { | |
| 244 column_set->AddColumn( | |
| 245 views::GridLayout::LEADING, | |
| 246 views::GridLayout::LEADING, | |
| 247 1, | |
| 248 views::GridLayout::USE_PREF, | |
| 249 0, | |
| 250 0); | |
| 251 } else { | |
| 252 int placeholders_count = kColumnsCount - column; | |
| 253 int placeholders_width = placeholders_count * | |
| 254 (kDefaultImageSize + 2 * kImageBorderSize); | |
| 255 int padding_width = (placeholders_count - 1) * kHorizontalPadding; | |
| 256 column_set->AddPaddingColumn(1, placeholders_width + padding_width); | |
| 257 break; | |
| 258 } | |
| 259 ++current_image; | |
| 260 } | |
| 261 } | |
| 262 current_image = 0; | |
| 263 for (int row = 0; row < rows_count; ++row) { | |
| 264 if (row != 0) | |
| 265 layout->AddPaddingRow(1, kVerticalPadding); | |
| 266 layout->StartRow(0, row); | |
| 267 for (int column = 0; column < kColumnsCount; ++column) { | |
| 268 if (current_image >= image_count) | |
| 269 break; | |
| 270 layout->AddView(default_images_[current_image]); | |
| 271 ++current_image; | |
| 272 } | |
| 273 } | |
| 274 } | |
| 275 | |
| 276 void DefaultImagesView::UpdateSelectedImage() { | |
| 277 if (selected_image_index_ == kCaptureButtonIndex) { | |
| 278 // If they selected the camera button, turn on the webcam. | |
| 279 if (delegate_) | |
| 280 delegate_->OnCaptureButtonClicked(); | |
| 281 } else if (selected_image_index_ >= kNonDefaultImageButtonsCount && | |
| 282 selected_image_index_ < kNonDefaultImageButtonsCount + | |
| 283 kDefaultImagesCount) { | |
| 284 if (delegate_) | |
| 285 delegate_->OnImageSelected( | |
| 286 (selected_image_index_ - kNonDefaultImageButtonsCount) % | |
| 287 kDefaultImagesCount); | |
| 288 } | |
| 289 } | |
| 290 | |
| 291 | |
| 292 } // namespace chromeos | |
| OLD | NEW |