Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: ui/message_center/notification_view.cc

Issue 12326091: Made notification center notifications collapsed and expandable. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Implemented review suggestions. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/message_center/notification_view.h" 5 #include "ui/message_center/notification_view.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "grit/ui_resources.h" 9 #include "grit/ui_resources.h"
10 #include "ui/base/accessibility/accessible_view_state.h" 10 #include "ui/base/accessibility/accessible_view_state.h"
11 #include "ui/base/resource/resource_bundle.h" 11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/base/text/text_elider.h" 12 #include "ui/base/text/text_elider.h"
13 #include "ui/gfx/canvas.h"
13 #include "ui/gfx/size.h" 14 #include "ui/gfx/size.h"
14 #include "ui/message_center/message_center_constants.h" 15 #include "ui/message_center/message_center_constants.h"
15 #include "ui/message_center/message_center_switches.h" 16 #include "ui/message_center/message_center_switches.h"
16 #include "ui/message_center/message_simple_view.h" 17 #include "ui/message_center/message_simple_view.h"
17 #include "ui/message_center/notification.h" 18 #include "ui/message_center/notification.h"
19 #include "ui/message_center/notification_change_delegate.h"
18 #include "ui/message_center/notification_types.h" 20 #include "ui/message_center/notification_types.h"
19 #include "ui/native_theme/native_theme.h" 21 #include "ui/native_theme/native_theme.h"
20 #include "ui/views/controls/button/image_button.h" 22 #include "ui/views/controls/button/image_button.h"
21 #include "ui/views/controls/image_view.h" 23 #include "ui/views/controls/image_view.h"
22 #include "ui/views/controls/label.h" 24 #include "ui/views/controls/label.h"
23 #include "ui/views/layout/box_layout.h" 25 #include "ui/views/layout/box_layout.h"
24 #include "ui/views/layout/fill_layout.h" 26 #include "ui/views/layout/fill_layout.h"
25 #include "ui/views/layout/grid_layout.h" 27 #include "ui/views/layout/grid_layout.h"
26 28
27 namespace { 29 namespace {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 message->SetBackgroundColor(kMessageBackgroundColor); 90 message->SetBackgroundColor(kMessageBackgroundColor);
89 AddChildView(message); 91 AddChildView(message);
90 92
91 PreferredSizeChanged(); 93 PreferredSizeChanged();
92 SchedulePaint(); 94 SchedulePaint();
93 } 95 }
94 96
95 ItemView::~ItemView() { 97 ItemView::~ItemView() {
96 } 98 }
97 99
98 // ProportionalImageViews match their heights to their widths to preserve the 100 // ProportionalImageViews center their images to preserve their proportion.
99 // proportions of their images. 101 // Note that for this subclass of views::ImageView GetImageBounds() will return
102 // potentially incorrect values (this can't be fixed because GetImageBounds()
103 // is not virtual) and horizontal and vertical alignments will be ignored.
100 class ProportionalImageView : public views::ImageView { 104 class ProportionalImageView : public views::ImageView {
101 public: 105 public:
102 ProportionalImageView(); 106 ProportionalImageView();
103 virtual ~ProportionalImageView(); 107 virtual ~ProportionalImageView();
104 108
105 // Overridden from views::View. 109 // Overridden from views::View:
106 virtual int GetHeightForWidth(int width) OVERRIDE; 110 virtual int GetHeightForWidth(int width) OVERRIDE;
111 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
107 112
108 private: 113 private:
114 gfx::Size GetImageSizeForWidth(int width);
115
109 DISALLOW_COPY_AND_ASSIGN(ProportionalImageView); 116 DISALLOW_COPY_AND_ASSIGN(ProportionalImageView);
110 }; 117 };
111 118
112 ProportionalImageView::ProportionalImageView() { 119 ProportionalImageView::ProportionalImageView() {
113 } 120 }
114 121
115 ProportionalImageView::~ProportionalImageView() { 122 ProportionalImageView::~ProportionalImageView() {
116 } 123 }
117 124
118 int ProportionalImageView::GetHeightForWidth(int width) { 125 int ProportionalImageView::GetHeightForWidth(int width) {
119 int height = 0; 126 return GetImageSizeForWidth(width).height();
120 gfx::ImageSkia image = GetImage(); 127 }
121 if (image.width() > 0 && image.height() > 0) { 128
122 double proportion = image.height() / (double) image.width(); 129 void ProportionalImageView::OnPaint(gfx::Canvas* canvas) {
123 height = 0.5 + width * proportion; 130 View::OnPaint(canvas);
124 if (height > message_center::kNotificationMaximumImageHeight) { 131
125 height = message_center::kNotificationMaximumImageHeight; 132 gfx::Size draw_size(GetImageSizeForWidth(width()));
126 width = 0.5 + height / proportion; 133 if (!draw_size.IsEmpty()) {
134 int x = (width() - draw_size.width()) / 2;
135 int y = (height() - draw_size.height()) / 2;
136
137 gfx::Size image_size(GetImage().size());
138 if (image_size == draw_size) {
139 canvas->DrawImageInt(GetImage(), x, y);
140 } else {
141 // Resize case
142 SkPaint paint;
143 paint.setFilterBitmap(true);
144 canvas->DrawImageInt(GetImage(), 0, 0,
145 image_size.width(), image_size.height(), x, y,
146 draw_size.width(), draw_size.height(), true, paint);
127 } 147 }
128 SetImageSize(gfx::Size(width, height));
129 } 148 }
130 return height; 149 }
150
151 gfx::Size ProportionalImageView::GetImageSizeForWidth(int width) {
152 gfx::Size size(GetImage().size());
153 if (width > 0 && !size.IsEmpty()) {
154 double proportion = size.height() / (double) size.width();
155 size.SetSize(width, std::max(0.5 + width * proportion, 1.0));
156 if (size.height() > message_center::kNotificationMaximumImageHeight) {
157 int height = message_center::kNotificationMaximumImageHeight;
158 size.SetSize(std::max(0.5 + height / proportion, 1.0), height);
159 }
160 }
161 return size;
131 } 162 }
132 163
133 // NotificationsButtons render the action buttons of notifications. 164 // NotificationsButtons render the action buttons of notifications.
134 class NotificationButton : public views::CustomButton { 165 class NotificationButton : public views::CustomButton {
135 public: 166 public:
136 NotificationButton(views::ButtonListener* listener); 167 NotificationButton(views::ButtonListener* listener);
137 virtual ~NotificationButton(); 168 virtual ~NotificationButton();
138 169
139 void SetIcon(const gfx::ImageSkia& icon); 170 void SetIcon(const gfx::ImageSkia& icon);
140 void SetTitle(const string16& title); 171 void SetTitle(const string16& title);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 title_->set_border(MakePadding(kActionButtonTitleTopPadding, 0, 0, 0)); 219 title_->set_border(MakePadding(kActionButtonTitleTopPadding, 0, 0, 0));
189 AddChildView(title_); 220 AddChildView(title_);
190 } 221 }
191 } 222 }
192 223
193 } // namespace 224 } // namespace
194 225
195 namespace message_center { 226 namespace message_center {
196 227
197 // static 228 // static
198 MessageView* NotificationView::Create( 229 MessageView* NotificationView::Create(const Notification& notification,
199 const Notification& notification, 230 NotificationChangeDelegate* delegate,
200 NotificationList::Delegate* list_delegate) { 231 bool expanded) {
201 // For the time being, use MessageSimpleView for simple notifications unless 232 // For the time being, use MessageSimpleView for simple notifications unless
202 // one of the use-the-new-style flags are set. This preserves the appearance 233 // one of the use-the-new-style flags are set. This preserves the appearance
203 // of notifications created by existing code that uses webkitNotifications. 234 // of notifications created by existing code that uses webkitNotifications.
204 if (notification.type() == NOTIFICATION_TYPE_SIMPLE && 235 if (notification.type() == NOTIFICATION_TYPE_SIMPLE &&
205 !CommandLine::ForCurrentProcess()->HasSwitch( 236 !CommandLine::ForCurrentProcess()->HasSwitch(
206 message_center::switches::kEnableRichNotifications) && 237 message_center::switches::kEnableRichNotifications) &&
207 !CommandLine::ForCurrentProcess()->HasSwitch( 238 !CommandLine::ForCurrentProcess()->HasSwitch(
208 message_center::switches::kEnableNewSimpleNotifications)) { 239 message_center::switches::kEnableNewSimpleNotifications)) {
209 return new MessageSimpleView(list_delegate, notification); 240 return new MessageSimpleView(notification, delegate);
210 } 241 }
211 242
212 switch (notification.type()) { 243 switch (notification.type()) {
213 case NOTIFICATION_TYPE_BASE_FORMAT: 244 case NOTIFICATION_TYPE_BASE_FORMAT:
214 case NOTIFICATION_TYPE_IMAGE: 245 case NOTIFICATION_TYPE_IMAGE:
215 case NOTIFICATION_TYPE_MULTIPLE: 246 case NOTIFICATION_TYPE_MULTIPLE:
216 case NOTIFICATION_TYPE_SIMPLE: 247 case NOTIFICATION_TYPE_SIMPLE:
217 break; 248 break;
218 default: 249 default:
219 // If the caller asks for an unrecognized kind of view (entirely possible 250 // If the caller asks for an unrecognized kind of view (entirely possible
220 // if an application is running on an older version of this code that 251 // if an application is running on an older version of this code that
221 // doesn't have the requested kind of notification template), we'll fall 252 // doesn't have the requested kind of notification template), we'll fall
222 // back to a notification instance that will provide at least basic 253 // back to a notification instance that will provide at least basic
223 // functionality. 254 // functionality.
224 LOG(WARNING) << "Unable to fulfill request for unrecognized " 255 LOG(WARNING) << "Unable to fulfill request for unrecognized "
225 << "notification type " << notification.type() << ". " 256 << "notification type " << notification.type() << ". "
226 << "Falling back to simple notification type."; 257 << "Falling back to simple notification type.";
227 } 258 }
228 259
229 // Currently all roads lead to the generic NotificationView. 260 // Currently all roads lead to the generic NotificationView.
230 return new NotificationView(list_delegate, notification); 261 return new NotificationView(notification, delegate, expanded);
231 } 262 }
232 263
233 NotificationView::NotificationView(NotificationList::Delegate* list_delegate, 264 NotificationView::NotificationView(const Notification& notification,
234 const Notification& notification) 265 NotificationChangeDelegate* delegate,
235 : MessageView(list_delegate, notification) { 266 bool expanded)
236 // This view is composed of two layers: The first layer has the notification 267 : MessageView(notification, delegate, expanded),
237 // content (text, images, action buttons, ...). This is overlaid by a second 268 content_view_(NULL),
238 // layer that has the notification close button and will later also have the 269 icon_view_(NULL) {
239 // expand button. This allows the close and expand buttons to overlap the 270 AddChildViews(notification);
240 // content as needed to provide a large enough click area
241 // (<http://crbug.com/168822> and touch area <http://crbug.com/168856>).
242 AddChildView(MakeContentView(notification));
243 AddChildView(close_button());
244 } 271 }
245 272
246 NotificationView::~NotificationView() { 273 NotificationView::~NotificationView() {
247 } 274 }
248 275
249 void NotificationView::Layout() { 276 void NotificationView::Layout() {
250 if (content_view_) { 277 gfx::Rect content_bounds(GetLocalBounds());
251 gfx::Rect contents_bounds = GetContentsBounds(); 278 content_bounds.Inset(GetInsets());
252 content_view_->SetBoundsRect(contents_bounds); 279 content_view_->SetBoundsRect(content_bounds);
253 if (close_button()) { 280
254 gfx::Size size(close_button()->GetPreferredSize()); 281 gfx::Size close_size(close_button()->GetPreferredSize());
255 close_button()->SetBounds(contents_bounds.right() - size.width(), 0, 282 close_button()->SetBounds(content_bounds.right() - close_size.width(),
256 size.width(), size.height()); 283 content_bounds.y(),
257 } 284 close_size.width(),
258 } 285 close_size.height());
286
287 gfx::Rect icon_bounds(content_bounds.origin(), icon_view_->size());
288 gfx::Size expand_size(expand_button()->GetPreferredSize());
289 expand_button()->SetBounds(content_bounds.right() - expand_size.width(),
290 icon_bounds.bottom() - expand_size.height(),
291 expand_size.width(),
292 expand_size.height());
259 } 293 }
260 294
261 gfx::Size NotificationView::GetPreferredSize() { 295 gfx::Size NotificationView::GetPreferredSize() {
262 if (!content_view_) 296 gfx::Size size;
263 return gfx::Size(); 297 if (content_view_) {
264 gfx::Size size = content_view_->GetPreferredSize(); 298 size = content_view_->GetPreferredSize();
265 if (border()) { 299 if (border()) {
266 gfx::Insets border_insets = border()->GetInsets(); 300 gfx::Insets insets = border()->GetInsets();
267 size.Enlarge(border_insets.width(), border_insets.height()); 301 size.Enlarge(insets.width(), insets.height());
302 }
268 } 303 }
269 return size; 304 return size;
270 } 305 }
271 306
307 void NotificationView::Update(const Notification& notification) {
308 MessageView::Update(notification);
309 content_view_ = NULL;
310 icon_view_ = NULL;
311 action_buttons_.clear();
312 RemoveAllChildViews(true);
313 AddChildViews(notification);
314 PreferredSizeChanged();
315 SchedulePaint();
316 }
317
272 void NotificationView::ButtonPressed(views::Button* sender, 318 void NotificationView::ButtonPressed(views::Button* sender,
273 const ui::Event& event) { 319 const ui::Event& event) {
274 for (size_t i = 0; i < action_buttons_.size(); ++i) { 320 for (size_t i = 0; i < action_buttons_.size(); ++i) {
275 if (action_buttons_[i] == sender) { 321 if (sender == action_buttons_[i]) {
276 list_delegate()->OnButtonClicked(notification_id(), i); 322 delegate()->OnButtonClicked(notification_id(), i);
277 return; 323 return;
278 } 324 }
279 } 325 }
280 MessageView::ButtonPressed(sender, event); 326 MessageView::ButtonPressed(sender, event);
281 } 327 }
282 328
283 views::View* NotificationView::MakeContentView( 329 void NotificationView::AddChildViews(const Notification& notification) {
284 const Notification& notification) { 330 // Child views are in two layers: The first layer has the notification content
331 // (text, images, action buttons, ...). This is overlaid by a second layer
332 // that has the notification close and expand buttons. This allows the close
333 // and expand buttons to overlap the content as needed to provide large enough
334 // click and touch areas (<http://crbug.com/168822> and
335 // <http://crbug.com/168856>).
336 AddContentView(notification);
337 AddChildView(close_button());
338 if (!is_expanded()) {
339 AddChildView(expand_button());
340 }
341 }
342
343 void NotificationView::AddContentView(const Notification& notification) {
285 content_view_ = new views::View(); 344 content_view_ = new views::View();
286 content_view_->set_background( 345 content_view_->set_background(
287 views::Background::CreateSolidBackground(kBackgroundColor)); 346 views::Background::CreateSolidBackground(kBackgroundColor));
288 347
289 // The top part of the content view is composed of an icon view on the left 348 // The top part of the content view is composed of an icon view on the left
290 // and a certain number of text views on the right (title and message or list 349 // and a certain number of text views on the right (title and message or list
291 // items), followed by a padding view. Laying out the icon view will require 350 // items), followed by a padding view. Laying out the icon view will require
292 // information about the text views, so these are created first and collected 351 // information about the text views, so these are created first and collected
293 // in this vector. 352 // in this vector.
294 std::vector<views::View*> texts; 353 std::vector<views::View*> text_views;
295 354
296 // Title if it exists. 355 // Title if it exists.
297 if (!notification.title().empty()) { 356 if (!notification.title().empty()) {
298 views::Label* title = new views::Label(notification.title()); 357 views::Label* title = new views::Label(notification.title());
299 title->SetHorizontalAlignment(gfx::ALIGN_LEFT); 358 title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
300 title->SetElideBehavior(views::Label::ELIDE_AT_END); 359 if (is_expanded())
360 title->SetMultiLine(true);
361 else
362 title->SetElideBehavior(views::Label::ELIDE_AT_END);
301 title->SetFont(title->font().DeriveFont(4)); 363 title->SetFont(title->font().DeriveFont(4));
302 title->SetEnabledColor(kTitleColor); 364 title->SetEnabledColor(kTitleColor);
303 title->SetBackgroundColor(kTitleBackgroundColor); 365 title->SetBackgroundColor(kTitleBackgroundColor);
304 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextRightPadding)); 366 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextRightPadding));
305 texts.push_back(title); 367 text_views.push_back(title);
368 }
369
370 // List notification items up to a maximum if appropriate.
371 size_t items = notification.items().size();
372 items = std::min(items, is_expanded() ? kNotificationMaximumItems : 0ul);
373 for (size_t i = 0; i < items; ++i) {
374 ItemView* item = new ItemView(notification.items()[i]);
375 item->set_border(MakePadding(0, 0, 4, kTextRightPadding));
376 text_views.push_back(item);
306 } 377 }
307 378
308 // Message if appropriate. 379 // Message if appropriate.
309 if (notification.items().size() == 0 && 380 if (items == 0ul && !notification.message().empty()) {
310 !notification.message().empty()) {
311 views::Label* message = new views::Label(notification.message()); 381 views::Label* message = new views::Label(notification.message());
312 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); 382 message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
313 message->SetMultiLine(true); 383 if (is_expanded())
384 message->SetMultiLine(true);
385 else
386 message->SetElideBehavior(views::Label::ELIDE_AT_END);
314 message->SetEnabledColor(kMessageColor); 387 message->SetEnabledColor(kMessageColor);
315 message->SetBackgroundColor(kMessageBackgroundColor); 388 message->SetBackgroundColor(kMessageBackgroundColor);
316 message->set_border(MakePadding(0, 0, 3, kTextRightPadding)); 389 message->set_border(MakePadding(0, 0, 3, kTextRightPadding));
317 texts.push_back(message); 390 text_views.push_back(message);
318 }
319
320 // List notification items up to a maximum.
321 int items = std::min(notification.items().size(),
322 kNotificationMaximumItems);
323 for (int i = 0; i < items; ++i) {
324 ItemView* item = new ItemView(notification.items()[i]);
325 item->set_border(MakePadding(0, 0, 4, kTextRightPadding));
326 texts.push_back(item);
327 } 391 }
328 392
329 // Set up the content view with a fixed-width icon column on the left and a 393 // Set up the content view with a fixed-width icon column on the left and a
330 // text column on the right that consumes the remaining space. To minimize the 394 // text column on the right that consumes the remaining space. To minimize the
331 // number of columns and simplify column spanning, padding is applied to each 395 // number of columns and simplify column spanning, padding is applied to each
332 // view within columns instead of through padding columns. 396 // view within columns instead of through padding columns.
333 views::GridLayout* layout = new views::GridLayout(content_view_); 397 views::GridLayout* layout = new views::GridLayout(content_view_);
334 content_view_->SetLayoutManager(layout); 398 content_view_->SetLayoutManager(layout);
335 views::ColumnSet* columns = layout->AddColumnSet(0); 399 views::ColumnSet* columns = layout->AddColumnSet(0);
336 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 400 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
337 0, views::GridLayout::FIXED, 401 0, views::GridLayout::FIXED,
338 kIconColumnWidth + kIconToTextPadding, 402 kIconColumnWidth + kIconToTextPadding,
339 kIconColumnWidth + kIconToTextPadding); 403 kIconColumnWidth + kIconToTextPadding);
340 // Padding + icon + padding. 404 // Padding + icon + padding.
341 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 405 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
342 100, views::GridLayout::USE_PREF, 0, 0); 406 100, views::GridLayout::USE_PREF, 0, 0);
343 // Text + padding. 407 // Text + padding.
344 408
345 // Create the first row and its icon view, which spans all the text views 409 // Create the first row and its icon view, which spans all the text views
346 // to its right as well as the padding view below them. 410 // to its right as well as the padding view below them.
347 layout->StartRow(0, 0); 411 layout->StartRow(0, 0);
348 views::ImageView* icon = new views::ImageView(); 412 icon_view_ = new views::ImageView();
349 icon->SetImageSize(gfx::Size(message_center::kNotificationIconSize, 413 icon_view_->SetImageSize(gfx::Size(message_center::kNotificationIconSize,
350 message_center::kNotificationIconSize)); 414 message_center::kNotificationIconSize));
351 icon->SetImage(notification.primary_icon()); 415 icon_view_->SetImage(notification.icon());
352 icon->SetHorizontalAlignment(views::ImageView::LEADING); 416 icon_view_->SetHorizontalAlignment(views::ImageView::LEADING);
353 icon->SetVerticalAlignment(views::ImageView::LEADING); 417 icon_view_->SetVerticalAlignment(views::ImageView::LEADING);
354 icon->set_border(MakePadding(0, 0, 0, kIconToTextPadding)); 418 icon_view_->set_border(MakePadding(0, 0, 0, kIconToTextPadding));
355 layout->AddView(icon, 1, texts.size() + 1); 419 layout->AddView(icon_view_, 1, text_views.size() + 1);
356 420
357 // Add the text views, creating rows for them if necessary. 421 // Add the text views, creating rows for them if necessary.
358 for (size_t i = 0; i < texts.size(); ++i) { 422 for (size_t i = 0; i < text_views.size(); ++i) {
359 if (i > 0) { 423 if (i > 0) {
360 layout->StartRow(0, 0); 424 layout->StartRow(0, 0);
361 layout->SkipColumns(1); 425 layout->SkipColumns(1);
362 } 426 }
363 layout->AddView(texts[i]); 427 layout->AddView(text_views[i]);
364 } 428 }
365 429
366 // Add a text padding row if necessary. This adds some space between the last 430 // Add a text padding row if necessary. This adds some space between the last
367 // line of text and anything below it but it also ensures views above it are 431 // line of text and anything below it but it also ensures views above it are
368 // top-justified by expanding vertically to take up any extra space. 432 // top-justified by expanding vertically to take up any extra space.
369 if (texts.size() == 0) { 433 if (text_views.size() == 0) {
370 layout->SkipColumns(1); 434 layout->SkipColumns(1);
371 } else { 435 } else {
372 layout->StartRow(100, 0); 436 layout->StartRow(100, 0);
373 layout->SkipColumns(1); 437 layout->SkipColumns(1);
374 views::View* padding = new views::ImageView(); 438 views::View* padding = new views::ImageView();
375 padding->set_border(MakePadding(kTextBottomPadding, 1, 0, 0)); 439 padding->set_border(MakePadding(kTextBottomPadding, 1, 0, 0));
376 layout->AddView(padding); 440 layout->AddView(padding);
377 } 441 }
378 442
379 // Add an image row if appropriate. 443 // Add an image row if appropriate.
380 if (!notification.image().isNull()) { 444 if (is_expanded() && !notification.image().isNull()) {
381 layout->StartRow(0, 0); 445 layout->StartRow(0, 0);
382 views::ImageView* image = new ProportionalImageView(); 446 ProportionalImageView* image_view = new ProportionalImageView();
383 image->SetImageSize(notification.image().size()); 447 image_view->SetImage(notification.image());
384 image->SetImage(notification.image()); 448 layout->AddView(image_view, 2, 1);
385 image->SetHorizontalAlignment(views::ImageView::CENTER);
386 image->SetVerticalAlignment(views::ImageView::LEADING);
387 layout->AddView(image, 2, 1);
388 } 449 }
389 450
390 // Add action button rows. 451 // Add action button rows.
391 for (size_t i = 0; i < notification.buttons().size(); ++i) { 452 for (size_t i = 0; i < notification.buttons().size(); ++i) {
392 views::View* separator = new views::View(); 453 views::View* separator = new views::View();
393 separator->set_background(MakeBackground(kButtonSeparatorColor)); 454 separator->set_background(MakeBackground(kButtonSeparatorColor));
394 layout->StartRow(0, 0); 455 layout->StartRow(0, 0);
395 layout->AddView(separator, 2, 1, 456 layout->AddView(separator, 2, 1,
396 views::GridLayout::FILL, views::GridLayout::FILL, 0, 1); 457 views::GridLayout::FILL, views::GridLayout::FILL, 0, 1);
397 NotificationButton* button = new NotificationButton(this); 458 NotificationButton* button = new NotificationButton(this);
398 ButtonInfo button_info = notification.buttons()[i]; 459 ButtonInfo button_info = notification.buttons()[i];
399 button->SetTitle(button_info.title); 460 button->SetTitle(button_info.title);
400 button->SetIcon(button_info.icon); 461 button->SetIcon(button_info.icon);
401 action_buttons_.push_back(button); 462 action_buttons_.push_back(button);
402 layout->StartRow(0, 0); 463 layout->StartRow(0, 0);
403 layout->AddView(button, 2, 1, 464 layout->AddView(button, 2, 1,
404 views::GridLayout::FILL, views::GridLayout::FILL, 0, 40); 465 views::GridLayout::FILL, views::GridLayout::FILL, 0, 40);
405 } 466 }
406 467
407 return content_view_; 468 AddChildView(content_view_);
408 } 469 }
409 470
410 } // namespace message_center 471 } // namespace message_center
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698