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

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

Issue 12277024: Notificaitons refactor step 2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: steven's feedback Created 7 years, 10 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/size.h" 13 #include "ui/gfx/size.h"
14 #include "ui/message_center/message_center_constants.h" 14 #include "ui/message_center/message_center_constants.h"
15 #include "ui/message_center/message_center_switches.h" 15 #include "ui/message_center/message_center_switches.h"
16 #include "ui/message_center/message_simple_view.h" 16 #include "ui/message_center/message_simple_view.h"
17 #include "ui/message_center/notification.h"
18 #include "ui/message_center/notification_types.h"
17 #include "ui/native_theme/native_theme.h" 19 #include "ui/native_theme/native_theme.h"
18 #include "ui/views/controls/button/image_button.h" 20 #include "ui/views/controls/button/image_button.h"
19 #include "ui/views/controls/image_view.h" 21 #include "ui/views/controls/image_view.h"
20 #include "ui/views/controls/label.h" 22 #include "ui/views/controls/label.h"
21 #include "ui/views/layout/box_layout.h" 23 #include "ui/views/layout/box_layout.h"
22 #include "ui/views/layout/fill_layout.h" 24 #include "ui/views/layout/fill_layout.h"
23 #include "ui/views/layout/grid_layout.h" 25 #include "ui/views/layout/grid_layout.h"
24 26
25 namespace { 27 namespace {
26 28
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 194
193 namespace message_center { 195 namespace message_center {
194 196
195 // static 197 // static
196 MessageView* NotificationView::ViewForNotification( 198 MessageView* NotificationView::ViewForNotification(
197 const Notification& notification, 199 const Notification& notification,
198 NotificationList::Delegate* list_delegate) { 200 NotificationList::Delegate* list_delegate) {
199 // For the time being, use MessageSimpleView for simple notifications unless 201 // For the time being, use MessageSimpleView for simple notifications unless
200 // one of the use-the-new-style flags are set. This preserves the appearance 202 // one of the use-the-new-style flags are set. This preserves the appearance
201 // of notifications created by existing code that uses webkitNotifications. 203 // of notifications created by existing code that uses webkitNotifications.
202 if (notification.type == ui::notifications::NOTIFICATION_TYPE_SIMPLE && 204 if (notification.type() == NOTIFICATION_TYPE_SIMPLE &&
203 !CommandLine::ForCurrentProcess()->HasSwitch( 205 !CommandLine::ForCurrentProcess()->HasSwitch(
204 message_center::switches::kEnableRichNotifications) && 206 message_center::switches::kEnableRichNotifications) &&
205 !CommandLine::ForCurrentProcess()->HasSwitch( 207 !CommandLine::ForCurrentProcess()->HasSwitch(
206 message_center::switches::kEnableNewSimpleNotifications)) { 208 message_center::switches::kEnableNewSimpleNotifications)) {
207 return new MessageSimpleView(list_delegate, notification); 209 scoped_ptr<MessageSimpleView> result(new MessageSimpleView(list_delegate));
210 result->SetUpView(notification);
211 return result.release();
208 } 212 }
209 213
210 switch (notification.type) { 214 switch (notification.type()) {
211 case ui::notifications::NOTIFICATION_TYPE_BASE_FORMAT: 215 case NOTIFICATION_TYPE_BASE_FORMAT:
212 case ui::notifications::NOTIFICATION_TYPE_IMAGE: 216 case NOTIFICATION_TYPE_IMAGE:
213 case ui::notifications::NOTIFICATION_TYPE_MULTIPLE: 217 case NOTIFICATION_TYPE_MULTIPLE:
214 case ui::notifications::NOTIFICATION_TYPE_SIMPLE: 218 case NOTIFICATION_TYPE_SIMPLE:
215 break; 219 break;
216 default: 220 default:
217 // If the caller asks for an unrecognized kind of view (entirely possible 221 // If the caller asks for an unrecognized kind of view (entirely possible
218 // if an application is running on an older version of this code that 222 // if an application is running on an older version of this code that
219 // doesn't have the requested kind of notification template), we'll fall 223 // doesn't have the requested kind of notification template), we'll fall
220 // back to a notification instance that will provide at least basic 224 // back to a notification instance that will provide at least basic
221 // functionality. 225 // functionality.
222 LOG(WARNING) << "Unable to fulfill request for unrecognized " 226 LOG(WARNING) << "Unable to fulfill request for unrecognized "
223 << "notification type " << notification.type << ". " 227 << "notification type " << notification.type() << ". "
224 << "Falling back to simple notification type."; 228 << "Falling back to simple notification type.";
225 } 229 }
226 230
227 // Currently all roads lead to the generic NotificationView. 231 // Currently all roads lead to the generic NotificationView.
228 return new NotificationView(list_delegate, notification); 232 scoped_ptr<NotificationView> result(new NotificationView(list_delegate));
233 result->SetUpView(notification);
234 return result.release();
229 } 235 }
230 236
231 NotificationView::NotificationView( 237 NotificationView::NotificationView(NotificationList::Delegate* list_delegate)
232 NotificationList::Delegate* list_delegate, 238 : MessageView(list_delegate) {
233 const Notification& notification)
234 : MessageView(list_delegate, notification) {
235 } 239 }
236 240
237 NotificationView::~NotificationView() { 241 NotificationView::~NotificationView() {
238 } 242 }
239 243
240 void NotificationView::Layout() { 244 void NotificationView::Layout() {
241 if (content_view_) { 245 if (content_view_) {
242 gfx::Rect contents_bounds = GetContentsBounds(); 246 gfx::Rect contents_bounds = GetContentsBounds();
243 content_view_->SetBoundsRect(contents_bounds); 247 content_view_->SetBoundsRect(contents_bounds);
244 if (close_button()) { 248 if (close_button()) {
245 gfx::Size size(close_button()->GetPreferredSize()); 249 gfx::Size size(close_button()->GetPreferredSize());
246 close_button()->SetBounds(contents_bounds.right() - size.width(), 0, 250 close_button()->SetBounds(contents_bounds.right() - size.width(), 0,
247 size.width(), size.height()); 251 size.width(), size.height());
248 } 252 }
249 } 253 }
250 } 254 }
251 255
252 gfx::Size NotificationView::GetPreferredSize() { 256 gfx::Size NotificationView::GetPreferredSize() {
253 if (!content_view_) 257 if (!content_view_)
254 return gfx::Size(); 258 return gfx::Size();
255 gfx::Size size = content_view_->GetPreferredSize(); 259 gfx::Size size = content_view_->GetPreferredSize();
256 if (border()) { 260 if (border()) {
257 gfx::Insets border_insets = border()->GetInsets(); 261 gfx::Insets border_insets = border()->GetInsets();
258 size.Enlarge(border_insets.width(), border_insets.height()); 262 size.Enlarge(border_insets.width(), border_insets.height());
259 } 263 }
260 return size; 264 return size;
261 } 265 }
262 266
263 void NotificationView::SetUpView() { 267 void NotificationView::SetUpView(const Notification& notification) {
268 MessageView::SetUpView(notification);
264 // This view is composed of two layers: The first layer has the notification 269 // This view is composed of two layers: The first layer has the notification
265 // content (text, images, action buttons, ...). This is overlaid by a second 270 // content (text, images, action buttons, ...). This is overlaid by a second
266 // layer that has the notification close button and will later also have the 271 // layer that has the notification close button and will later also have the
267 // expand button. This allows the close and expand buttons to overlap the 272 // expand button. This allows the close and expand buttons to overlap the
268 // content as needed to provide a large enough click area 273 // content as needed to provide a large enough click area
269 // (<http://crbug.com/168822> and touch area <http://crbug.com/168856>). 274 // (<http://crbug.com/168822> and touch area <http://crbug.com/168856>).
270 AddChildView(MakeContentView()); 275 AddChildView(MakeContentView(notification));
271 AddChildView(close_button()); 276 AddChildView(close_button());
272 } 277 }
273 278
274 void NotificationView::ButtonPressed(views::Button* sender, 279 void NotificationView::ButtonPressed(views::Button* sender,
275 const ui::Event& event) { 280 const ui::Event& event) {
276 for (size_t i = 0; i < action_buttons_.size(); ++i) { 281 for (size_t i = 0; i < action_buttons_.size(); ++i) {
277 if (action_buttons_[i] == sender) { 282 if (action_buttons_[i] == sender) {
278 list_delegate()->OnButtonClicked(notification().id, i); 283 list_delegate()->OnButtonClicked(notification_id(), i);
279 return; 284 return;
280 } 285 }
281 } 286 }
282 MessageView::ButtonPressed(sender, event); 287 MessageView::ButtonPressed(sender, event);
283 } 288 }
284 289
285 views::View* NotificationView::MakeContentView() { 290 views::View* NotificationView::MakeContentView(
291 const Notification& notification) {
286 content_view_ = new views::View(); 292 content_view_ = new views::View();
287 content_view_->set_background( 293 content_view_->set_background(
288 views::Background::CreateSolidBackground(kBackgroundColor)); 294 views::Background::CreateSolidBackground(kBackgroundColor));
289 295
290 // The top part of the content view is composed of an icon view on the left 296 // The top part of the content view is composed of an icon view on the left
291 // and a certain number of text views on the right (title and message or list 297 // and a certain number of text views on the right (title and message or list
292 // items), followed by a padding view. Laying out the icon view will require 298 // items), followed by a padding view. Laying out the icon view will require
293 // information about the text views, so these are created first and collected 299 // information about the text views, so these are created first and collected
294 // in this vector. 300 // in this vector.
295 std::vector<views::View*> texts; 301 std::vector<views::View*> texts;
296 302
297 // Title if it exists. 303 // Title if it exists.
298 if (!notification().title.empty()) { 304 if (!notification.title().empty()) {
299 views::Label* title = new views::Label(notification().title); 305 views::Label* title = new views::Label(notification.title());
300 title->SetHorizontalAlignment(gfx::ALIGN_LEFT); 306 title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
301 title->SetElideBehavior(views::Label::ELIDE_AT_END); 307 title->SetElideBehavior(views::Label::ELIDE_AT_END);
302 title->SetFont(title->font().DeriveFont(4)); 308 title->SetFont(title->font().DeriveFont(4));
303 title->SetEnabledColor(kTitleColor); 309 title->SetEnabledColor(kTitleColor);
304 title->SetBackgroundColor(kTitleBackgroundColor); 310 title->SetBackgroundColor(kTitleBackgroundColor);
305 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextRightPadding)); 311 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextRightPadding));
306 texts.push_back(title); 312 texts.push_back(title);
307 } 313 }
308 314
309 // Message if appropriate. 315 // Message if appropriate.
310 if (notification().items.size() == 0 && !notification().message.empty()) { 316 if (notification.items().size() == 0 &&
311 views::Label* message = new views::Label(notification().message); 317 !notification.message().empty()) {
318 views::Label* message = new views::Label(notification.message());
312 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); 319 message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
313 message->SetMultiLine(true); 320 message->SetMultiLine(true);
314 message->SetEnabledColor(kMessageColor); 321 message->SetEnabledColor(kMessageColor);
315 message->SetBackgroundColor(kMessageBackgroundColor); 322 message->SetBackgroundColor(kMessageBackgroundColor);
316 message->set_border(MakePadding(0, 0, 3, kTextRightPadding)); 323 message->set_border(MakePadding(0, 0, 3, kTextRightPadding));
317 texts.push_back(message); 324 texts.push_back(message);
318 } 325 }
319 326
320 // List notification items up to a maximum. 327 // List notification items up to a maximum.
321 int items = std::min(notification().items.size(), kNotificationMaximumItems); 328 int items = std::min(notification.items().size(),
329 kNotificationMaximumItems);
322 for (int i = 0; i < items; ++i) { 330 for (int i = 0; i < items; ++i) {
323 ItemView* item = new ItemView(notification().items[i]); 331 ItemView* item = new ItemView(notification.items()[i]);
324 item->set_border(MakePadding(0, 0, 4, kTextRightPadding)); 332 item->set_border(MakePadding(0, 0, 4, kTextRightPadding));
325 texts.push_back(item); 333 texts.push_back(item);
326 } 334 }
327 335
328 // Set up the content view with a fixed-width icon column on the left and a 336 // Set up the content view with a fixed-width icon column on the left and a
329 // text column on the right that consumes the remaining space. To minimize the 337 // text column on the right that consumes the remaining space. To minimize the
330 // number of columns and simplify column spanning, padding is applied to each 338 // number of columns and simplify column spanning, padding is applied to each
331 // view within columns instead of through padding columns. 339 // view within columns instead of through padding columns.
332 views::GridLayout* layout = new views::GridLayout(content_view_); 340 views::GridLayout* layout = new views::GridLayout(content_view_);
333 content_view_->SetLayoutManager(layout); 341 content_view_->SetLayoutManager(layout);
334 views::ColumnSet* columns = layout->AddColumnSet(0); 342 views::ColumnSet* columns = layout->AddColumnSet(0);
335 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 343 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
336 0, views::GridLayout::FIXED, 344 0, views::GridLayout::FIXED,
337 kIconColumnWidth + kIconToTextPadding, 345 kIconColumnWidth + kIconToTextPadding,
338 kIconColumnWidth + kIconToTextPadding); 346 kIconColumnWidth + kIconToTextPadding);
339 // Padding + icon + padding. 347 // Padding + icon + padding.
340 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 348 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
341 100, views::GridLayout::USE_PREF, 0, 0); 349 100, views::GridLayout::USE_PREF, 0, 0);
342 // Text + padding. 350 // Text + padding.
343 351
344 // Create the first row and its icon view, which spans all the text views 352 // Create the first row and its icon view, which spans all the text views
345 // to its right as well as the padding view below them. 353 // to its right as well as the padding view below them.
346 layout->StartRow(0, 0); 354 layout->StartRow(0, 0);
347 views::ImageView* icon = new views::ImageView(); 355 views::ImageView* icon = new views::ImageView();
348 icon->SetImageSize(gfx::Size(message_center::kNotificationIconSize, 356 icon->SetImageSize(gfx::Size(message_center::kNotificationIconSize,
349 message_center::kNotificationIconSize)); 357 message_center::kNotificationIconSize));
350 icon->SetImage(notification().primary_icon); 358 icon->SetImage(notification.primary_icon());
351 icon->SetHorizontalAlignment(views::ImageView::LEADING); 359 icon->SetHorizontalAlignment(views::ImageView::LEADING);
352 icon->SetVerticalAlignment(views::ImageView::LEADING); 360 icon->SetVerticalAlignment(views::ImageView::LEADING);
353 icon->set_border(MakePadding(0, 0, 0, kIconToTextPadding)); 361 icon->set_border(MakePadding(0, 0, 0, kIconToTextPadding));
354 layout->AddView(icon, 1, texts.size() + 1); 362 layout->AddView(icon, 1, texts.size() + 1);
355 363
356 // Add the text views, creating rows for them if necessary. 364 // Add the text views, creating rows for them if necessary.
357 for (size_t i = 0; i < texts.size(); ++i) { 365 for (size_t i = 0; i < texts.size(); ++i) {
358 if (i > 0) { 366 if (i > 0) {
359 layout->StartRow(0, 0); 367 layout->StartRow(0, 0);
360 layout->SkipColumns(1); 368 layout->SkipColumns(1);
361 } 369 }
362 layout->AddView(texts[i]); 370 layout->AddView(texts[i]);
363 } 371 }
364 372
365 // Add a text padding row if necessary. This adds some space between the last 373 // Add a text padding row if necessary. This adds some space between the last
366 // line of text and anything below it but it also ensures views above it are 374 // line of text and anything below it but it also ensures views above it are
367 // top-justified by expanding vertically to take up any extra space. 375 // top-justified by expanding vertically to take up any extra space.
368 if (texts.size() == 0) { 376 if (texts.size() == 0) {
369 layout->SkipColumns(1); 377 layout->SkipColumns(1);
370 } else { 378 } else {
371 layout->StartRow(100, 0); 379 layout->StartRow(100, 0);
372 layout->SkipColumns(1); 380 layout->SkipColumns(1);
373 views::View* padding = new views::ImageView(); 381 views::View* padding = new views::ImageView();
374 padding->set_border(MakePadding(kTextBottomPadding, 1, 0, 0)); 382 padding->set_border(MakePadding(kTextBottomPadding, 1, 0, 0));
375 layout->AddView(padding); 383 layout->AddView(padding);
376 } 384 }
377 385
378 // Add an image row if appropriate. 386 // Add an image row if appropriate.
379 if (!notification().image.isNull()) { 387 if (!notification.image().isNull()) {
380 layout->StartRow(0, 0); 388 layout->StartRow(0, 0);
381 views::ImageView* image = new ProportionalImageView(); 389 views::ImageView* image = new ProportionalImageView();
382 image->SetImageSize(notification().image.size()); 390 image->SetImageSize(notification.image().size());
383 image->SetImage(notification().image); 391 image->SetImage(notification.image());
384 image->SetHorizontalAlignment(views::ImageView::CENTER); 392 image->SetHorizontalAlignment(views::ImageView::CENTER);
385 image->SetVerticalAlignment(views::ImageView::LEADING); 393 image->SetVerticalAlignment(views::ImageView::LEADING);
386 layout->AddView(image, 2, 1); 394 layout->AddView(image, 2, 1);
387 } 395 }
388 396
389 // Add action button rows. 397 // Add action button rows.
390 for (size_t i = 0; i < notification().button_titles.size(); ++i) { 398 for (size_t i = 0; i < notification.buttons().size(); ++i) {
391 views::View* separator = new views::View(); 399 views::View* separator = new views::View();
392 separator->set_background(MakeBackground(kButtonSeparatorColor)); 400 separator->set_background(MakeBackground(kButtonSeparatorColor));
393 layout->StartRow(0, 0); 401 layout->StartRow(0, 0);
394 layout->AddView(separator, 2, 1, 402 layout->AddView(separator, 2, 1,
395 views::GridLayout::FILL, views::GridLayout::FILL, 0, 1); 403 views::GridLayout::FILL, views::GridLayout::FILL, 0, 1);
396 NotificationButton* button = new NotificationButton(this); 404 NotificationButton* button = new NotificationButton(this);
397 button->SetTitle(notification().button_titles[i]); 405 ButtonInfo button_info = notification.buttons()[i];
398 button->SetIcon(notification().button_icons[i]); 406 button->SetTitle(button_info.title);
407 button->SetIcon(button_info.icon);
399 action_buttons_.push_back(button); 408 action_buttons_.push_back(button);
400 layout->StartRow(0, 0); 409 layout->StartRow(0, 0);
401 layout->AddView(button, 2, 1, 410 layout->AddView(button, 2, 1,
402 views::GridLayout::FILL, views::GridLayout::FILL, 0, 40); 411 views::GridLayout::FILL, views::GridLayout::FILL, 0, 40);
403 } 412 }
404 413
405 return content_view_; 414 return content_view_;
406 } 415 }
407 416
408 } // namespace message_center 417 } // namespace message_center
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698