• 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/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/theme_resources.h"
12 #include "grit/generated_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/border.h"
18 #include "views/background.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 // A number of the first buttons that don't correspond to any default image
50 // (i.e. button to take a photo).
51 const int kNonDefaultImageButtonsCount = 1;
52 
53 }  // namespace
54 
55 // Image button with border and background. Corrects view size by border
56 // insets as ImageButton ignores it.
57 class UserImageButton : public views::ImageButton {
58  public:
59   explicit UserImageButton(views::ButtonListener* listener);
60 
61   // Overridden from views::View:
62   virtual gfx::Size GetPreferredSize();
63 
64  private:
65   DISALLOW_COPY_AND_ASSIGN(UserImageButton);
66 };
67 
UserImageButton(views::ButtonListener * listener)68 UserImageButton::UserImageButton(views::ButtonListener* listener)
69     : ImageButton(listener) {
70   set_border(
71       views::Border::CreateSolidBorder(kImageBorderSize, kImageBorderColor));
72   set_background(
73       views::Background::CreateSolidBackground(kImageBackgroundColor));
74   SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
75 }
76 
GetPreferredSize()77 gfx::Size UserImageButton::GetPreferredSize() {
78   gfx::Size size = views::ImageButton::GetPreferredSize();
79   size.Enlarge(GetInsets().width(), GetInsets().height());
80   return size;
81 }
82 
83 
DefaultImagesView(Delegate * delegate)84 DefaultImagesView::DefaultImagesView(Delegate* delegate)
85     : selected_image_index_(-1),
86       delegate_(delegate) {
87 }
88 
Init()89 void DefaultImagesView::Init() {
90   UserImageButton* capture_button = new UserImageButton(this);
91   capture_button->SetID(kCaptureButtonId);
92   capture_button->SetTooltipText(UTF16ToWide(
93       l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO)));
94   InitButton(IDR_BUTTON_USER_IMAGE_TAKE_PHOTO, capture_button);
95   default_images_.push_back(capture_button);
96   for (int i = 0; i < kDefaultImagesCount; ++i) {
97     UserImageButton* image_button = new UserImageButton(this);
98     image_button->SetID(i + kImageStartId);
99     InitButton(kDefaultImageResources[i], image_button);
100     default_images_.push_back(image_button);
101   }
102   InitLayout();
103 }
104 
GetDefaultImageIndex() const105 int DefaultImagesView::GetDefaultImageIndex() const {
106   if (selected_image_index_ == -1)
107     return -1;
108   else
109     return selected_image_index_ - kNonDefaultImageButtonsCount;
110 }
111 
SetDefaultImageIndex(int image_index)112 void DefaultImagesView::SetDefaultImageIndex(int image_index) {
113   selected_image_index_ = image_index + kNonDefaultImageButtonsCount;
114   if (delegate_)
115     delegate_->OnImageSelected(image_index % kDefaultImagesCount);
116 }
117 
ClearSelection()118 void DefaultImagesView::ClearSelection() {
119   selected_image_index_ = -1;
120 }
121 
GetPreferredSize()122 gfx::Size DefaultImagesView::GetPreferredSize() {
123   int image_size_with_margin = (kDefaultImageSize + 2 * kImageBorderSize);
124   int width = kColumnsCount * image_size_with_margin +
125               (kColumnsCount - 1) * kHorizontalPadding;
126   size_t image_count = default_images_.size();
127   int rows_count = (image_count + kColumnsCount - 1) / kColumnsCount;
128   int height = rows_count * image_size_with_margin +
129                (rows_count - 1) * kVerticalPadding;
130   return gfx::Size(width + 2 * kHorizontalMargin,
131                    height + 2 * kVerticalMargin);
132 }
133 
ButtonPressed(views::Button * sender,const views::Event & event)134 void DefaultImagesView::ButtonPressed(views::Button* sender,
135                                       const views::Event& event) {
136   if (selected_image_index_ != -1 &&
137       default_images_[selected_image_index_] == sender)
138     return;
139   ClearSelection();
140 
141   if (sender->GetID() == kCaptureButtonId) {
142     if (delegate_)
143       delegate_->OnCaptureButtonClicked();
144   } else {
145     int image_index = sender->GetID() - kImageStartId;
146     int images_count = static_cast<int>(default_images_.size());
147     if (image_index < 0 || image_index >= images_count) {
148       NOTREACHED() << "Got ButtonPressed event from a view with wrong id.";
149       return;
150     }
151     SetDefaultImageIndex(image_index);
152   }
153 }
154 
InitButton(int resource_id,UserImageButton * button) const155 void DefaultImagesView::InitButton(int resource_id,
156                                    UserImageButton* button) const {
157   const SkBitmap* original_image =
158       ResourceBundle::GetSharedInstance().GetBitmapNamed(resource_id);
159   SkBitmap resized_image = skia::ImageOperations::Resize(
160       *original_image,
161       skia::ImageOperations::RESIZE_BEST,
162       kDefaultImageSize, kDefaultImageSize);
163   button->SetImage(
164       views::CustomButton::BS_NORMAL,
165       &resized_image);
166 }
167 
InitLayout()168 void DefaultImagesView::InitLayout() {
169   views::GridLayout* layout = new views::GridLayout(this);
170   layout->SetInsets(gfx::Insets(kVerticalMargin,
171                                 kHorizontalMargin,
172                                 kVerticalMargin,
173                                 kHorizontalMargin));
174   SetLayoutManager(layout);
175 
176   size_t current_image = 0;
177   size_t image_count = default_images_.size();
178   int rows_count = (image_count + kColumnsCount - 1) / kColumnsCount;
179   for (int row = 0; row < rows_count; ++row) {
180     views::ColumnSet* column_set = layout->AddColumnSet(row);
181     for (int column = 0; column < kColumnsCount; ++column) {
182       if (column != 0)
183         column_set->AddPaddingColumn(1, kHorizontalPadding);
184       if (current_image < image_count) {
185         column_set->AddColumn(
186             views::GridLayout::LEADING,
187             views::GridLayout::LEADING,
188             1,
189             views::GridLayout::USE_PREF,
190             0,
191             0);
192       } else {
193         int placeholders_count = kColumnsCount - column;
194         int placeholders_width = placeholders_count *
195                                  (kDefaultImageSize + 2 * kImageBorderSize);
196         int padding_width = (placeholders_count - 1) * kHorizontalPadding;
197         column_set->AddPaddingColumn(1, placeholders_width + padding_width);
198         break;
199       }
200       ++current_image;
201     }
202   }
203   current_image = 0;
204   for (int row = 0; row < rows_count; ++row) {
205     if (row != 0)
206       layout->AddPaddingRow(1, kVerticalPadding);
207     layout->StartRow(0, row);
208     for (int column = 0; column < kColumnsCount; ++column) {
209       if (current_image >= image_count)
210         break;
211       layout->AddView(default_images_[current_image]);
212       ++current_image;
213     }
214   }
215 }
216 
217 }  // namespace chromeos
218