OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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 <algorithm> | |
8 | |
9 #include "app/l10n_util.h" | |
10 #include "app/resource_bundle.h" | |
11 #include "base/callback.h" | |
12 #include "chrome/browser/chromeos/login/rounded_rect_painter.h" | |
13 #include "gfx/canvas.h" | |
14 #include "grit/generated_resources.h" | |
15 #include "grit/theme_resources.h" | |
16 #include "skia/ext/image_operations.h" | |
17 #include "views/controls/button/image_button.h" | |
18 #include "views/controls/button/native_button.h" | |
19 #include "views/controls/image_view.h" | |
20 #include "views/controls/label.h" | |
21 | |
22 namespace { | |
23 | |
24 // Margin in pixels from the left and right borders of screen's contents. | |
25 const int kHorizontalMargin = 10; | |
26 // Margin in pixels from the top and bottom borders of screen's contents. | |
27 const int kVerticalMargin = 10; | |
28 // Padding between horizontally neighboring elements. | |
29 const int kHorizontalPadding = 10; | |
30 // Padding between vertically neighboring elements. | |
31 const int kVerticalPadding = 10; | |
32 // Size of each image in images list. | |
33 const int kImageSize = 160; | |
34 // Size of selected image preview. | |
35 const int kSelectedImageSize = 260; | |
36 | |
37 } // namespace | |
38 | |
39 namespace chromeos { | |
40 | |
41 UserImageView::UserImageView(Delegate* delegate) | |
42 : title_label_(NULL), | |
43 ok_button_(NULL), | |
44 cancel_button_(NULL), | |
45 video_button_(NULL), | |
46 selected_image_(NULL), | |
47 delegate_(delegate), | |
48 image_selected_(false) { | |
49 } | |
50 | |
51 UserImageView::~UserImageView() { | |
52 } | |
53 | |
54 void UserImageView::Init() { | |
55 // Use rounded rect background. | |
56 set_border(CreateWizardBorder(&BorderDefinition::kScreenBorder)); | |
57 views::Painter* painter = CreateWizardPainter( | |
58 &BorderDefinition::kScreenBorder); | |
59 set_background(views::Background::CreateBackgroundPainter(true, painter)); | |
60 | |
61 // Set up fonts. | |
62 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
63 gfx::Font title_font = rb.GetFont(ResourceBundle::MediumBoldFont); | |
64 | |
65 title_label_ = new views::Label(); | |
66 title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
67 title_label_->SetFont(title_font); | |
68 title_label_->SetMultiLine(true); | |
69 AddChildView(title_label_); | |
70 | |
71 SkBitmap video_button_image( | |
72 skia::ImageOperations::Resize( | |
73 *ResourceBundle::GetSharedInstance().GetBitmapNamed( | |
74 IDR_USER_IMAGE_NO_VIDEO), | |
75 skia::ImageOperations::RESIZE_LANCZOS3, | |
76 kImageSize, | |
77 kImageSize)); | |
78 | |
79 video_button_ = new views::ImageButton(this); | |
80 video_button_->SetImage(views::CustomButton::BS_NORMAL, &video_button_image); | |
81 AddChildView(video_button_); | |
82 | |
83 selected_image_ = new views::ImageView(); | |
84 selected_image_->SetImageSize( | |
85 gfx::Size(kSelectedImageSize, kSelectedImageSize)); | |
86 selected_image_->SetImage( | |
87 *ResourceBundle::GetSharedInstance().GetBitmapNamed( | |
88 IDR_LOGIN_OTHER_USER)); | |
89 AddChildView(selected_image_); | |
90 | |
91 UpdateLocalizedStrings(); | |
92 } | |
93 | |
94 void UserImageView::RecreateNativeControls() { | |
95 // There is no way to get native button preferred size after the button was | |
96 // sized so delete and recreate the button on text update. | |
97 delete ok_button_; | |
98 ok_button_ = new views::NativeButton(this, std::wstring()); | |
99 AddChildView(ok_button_); | |
100 ok_button_->SetEnabled(image_selected_); | |
101 | |
102 delete cancel_button_; | |
103 cancel_button_ = new views::NativeButton(this, std::wstring()); | |
104 AddChildView(cancel_button_); | |
105 cancel_button_->SetEnabled(true); | |
106 } | |
107 | |
108 void UserImageView::UpdateLocalizedStrings() { | |
109 RecreateNativeControls(); | |
110 | |
111 title_label_->SetText(l10n_util::GetString(IDS_USER_IMAGE_SCREEN_TITLE)); | |
112 ok_button_->SetLabel(l10n_util::GetString(IDS_OK)); | |
113 cancel_button_->SetLabel(l10n_util::GetString(IDS_CANCEL)); | |
114 selected_image_->SetTooltipText( | |
115 l10n_util::GetString(IDS_USER_IMAGE_SELECTED_TOOLTIP)); | |
116 } | |
117 | |
118 void UserImageView::UpdateVideoFrame(const SkBitmap& frame) { | |
119 last_frame_.reset(new SkBitmap(frame)); | |
120 SkBitmap video_button_image( | |
121 skia::ImageOperations::Resize( | |
122 frame, | |
123 skia::ImageOperations::RESIZE_LANCZOS3, | |
124 kImageSize, | |
125 kImageSize)); | |
126 | |
127 video_button_->SetImage(views::CustomButton::BS_NORMAL, &video_button_image); | |
128 video_button_->SchedulePaint(); | |
129 } | |
130 | |
131 void UserImageView::OnVideoImageClicked() { | |
132 // TODO(avayvod): Snapshot sound. | |
133 if (!last_frame_.get()) | |
134 return; | |
135 selected_image_->SetImage(*last_frame_); | |
136 image_selected_ = true; | |
137 ok_button_->SetEnabled(true); | |
138 } | |
139 | |
140 void UserImageView::LocaleChanged() { | |
141 UpdateLocalizedStrings(); | |
142 Layout(); | |
143 } | |
144 | |
145 void UserImageView::Layout() { | |
146 gfx::Insets insets = GetInsets(); | |
147 | |
148 // Place title at the top. | |
149 int title_x = insets.left() + kHorizontalMargin; | |
150 int title_y = insets.top() + kVerticalMargin; | |
151 int max_width = width() - insets.width() - kHorizontalMargin * 2; | |
152 title_label_->SizeToFit(max_width); | |
153 | |
154 gfx::Size title_size = title_label_->GetPreferredSize(); | |
155 title_label_->SetBounds(title_x, | |
156 title_y, | |
157 std::min(max_width, title_size.width()), | |
158 title_size.height()); | |
159 | |
160 // Put OK button at the right bottom corner. | |
161 gfx::Size ok_size = ok_button_->GetPreferredSize(); | |
162 int ok_x = width() - insets.right() - kHorizontalMargin - ok_size.width(); | |
163 int ok_y = height() - insets.bottom() - kVerticalMargin - ok_size.height(); | |
164 ok_button_->SetBounds(ok_x, ok_y, ok_size.width(), ok_size.height()); | |
165 | |
166 // Put Cancel button to the left from OK. | |
167 gfx::Size cancel_size = cancel_button_->GetPreferredSize(); | |
168 int cancel_x = ok_x - kHorizontalPadding - cancel_size.width(); | |
169 int cancel_y = ok_y; // Height should be the same for both buttons. | |
170 cancel_button_->SetBounds(cancel_x, | |
171 cancel_y, | |
172 cancel_size.width(), | |
173 cancel_size.height()); | |
174 | |
175 // The area between buttons and title is for images. | |
176 int title_bottom = title_label_->y() + title_label_->height(); | |
177 gfx::Rect images_area(insets.left() + kHorizontalMargin, | |
178 title_bottom + kVerticalPadding, | |
179 max_width, | |
180 ok_button_->y() - title_bottom - | |
181 2 * kVerticalPadding); | |
182 | |
183 // Video capture image is in the top left corner of the area. | |
184 int video_button_x = images_area.x(); | |
185 int video_button_y = images_area.y(); | |
186 gfx::Size video_button_size = video_button_->GetPreferredSize(); | |
187 video_button_->SetBounds(video_button_x, | |
188 video_button_y, | |
189 video_button_size.width(), | |
190 video_button_size.height()); | |
191 | |
192 // Selected image is floating in the middle between top and height, near | |
193 // the right border. | |
194 gfx::Size selected_image_size = selected_image_->GetPreferredSize(); | |
195 int selected_image_x = images_area.right() - selected_image_size.width(); | |
196 int selected_image_y = images_area.y() + | |
197 (images_area.height() - selected_image_size.height()) / 2; | |
198 selected_image_->SetBounds(selected_image_x, | |
199 selected_image_y, | |
200 selected_image_size.width(), | |
201 selected_image_size.height()); | |
202 | |
203 SchedulePaint(); | |
204 } | |
205 | |
206 gfx::Size UserImageView::GetPreferredSize() { | |
207 return gfx::Size(width(), height()); | |
208 } | |
209 | |
210 void UserImageView::ButtonPressed( | |
211 views::Button* sender, const views::Event& event) { | |
212 DCHECK(delegate_); | |
213 if (sender == video_button_) { | |
214 OnVideoImageClicked(); | |
215 return; | |
216 } | |
217 if (sender == ok_button_) | |
218 delegate_->OnOK(*last_frame_); | |
219 else if (sender == cancel_button_) | |
220 delegate_->OnCancel(); | |
221 else | |
222 NOTREACHED(); | |
223 } | |
224 | |
225 } // namespace chromeos | |
226 | |
OLD | NEW |