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

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: more feedback from Steven 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
« no previous file with comments | « ui/message_center/notification_view.h ('k') | ui/notifications/OWNERS » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 return new MessageSimpleView(list_delegate, notification);
208 } 210 }
209 211
210 switch (notification.type) { 212 switch (notification.type()) {
211 case ui::notifications::NOTIFICATION_TYPE_BASE_FORMAT: 213 case NOTIFICATION_TYPE_BASE_FORMAT:
212 case ui::notifications::NOTIFICATION_TYPE_IMAGE: 214 case NOTIFICATION_TYPE_IMAGE:
213 case ui::notifications::NOTIFICATION_TYPE_MULTIPLE: 215 case NOTIFICATION_TYPE_MULTIPLE:
214 case ui::notifications::NOTIFICATION_TYPE_SIMPLE: 216 case NOTIFICATION_TYPE_SIMPLE:
215 break; 217 break;
216 default: 218 default:
217 // If the caller asks for an unrecognized kind of view (entirely possible 219 // 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 220 // 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 221 // doesn't have the requested kind of notification template), we'll fall
220 // back to a notification instance that will provide at least basic 222 // back to a notification instance that will provide at least basic
221 // functionality. 223 // functionality.
222 LOG(WARNING) << "Unable to fulfill request for unrecognized " 224 LOG(WARNING) << "Unable to fulfill request for unrecognized "
223 << "notification type " << notification.type << ". " 225 << "notification type " << notification.type() << ". "
224 << "Falling back to simple notification type."; 226 << "Falling back to simple notification type.";
225 } 227 }
226 228
227 // Currently all roads lead to the generic NotificationView. 229 // Currently all roads lead to the generic NotificationView.
228 return new NotificationView(list_delegate, notification); 230 return new NotificationView(list_delegate, notification);
229 } 231 }
230 232
231 NotificationView::NotificationView( 233 NotificationView::NotificationView(NotificationList::Delegate* list_delegate,
232 NotificationList::Delegate* list_delegate, 234 const Notification& notification)
233 const Notification& notification)
234 : MessageView(list_delegate, notification) { 235 : MessageView(list_delegate, notification) {
236 // This view is composed of two layers: The first layer has the notification
237 // content (text, images, action buttons, ...). This is overlaid by a second
238 // layer that has the notification close button and will later also have the
239 // expand button. This allows the close and expand buttons to overlap the
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());
235 } 244 }
236 245
237 NotificationView::~NotificationView() { 246 NotificationView::~NotificationView() {
238 } 247 }
239 248
240 void NotificationView::Layout() { 249 void NotificationView::Layout() {
241 if (content_view_) { 250 if (content_view_) {
242 gfx::Rect contents_bounds = GetContentsBounds(); 251 gfx::Rect contents_bounds = GetContentsBounds();
243 content_view_->SetBoundsRect(contents_bounds); 252 content_view_->SetBoundsRect(contents_bounds);
244 if (close_button()) { 253 if (close_button()) {
245 gfx::Size size(close_button()->GetPreferredSize()); 254 gfx::Size size(close_button()->GetPreferredSize());
246 close_button()->SetBounds(contents_bounds.right() - size.width(), 0, 255 close_button()->SetBounds(contents_bounds.right() - size.width(), 0,
247 size.width(), size.height()); 256 size.width(), size.height());
248 } 257 }
249 } 258 }
250 } 259 }
251 260
252 gfx::Size NotificationView::GetPreferredSize() { 261 gfx::Size NotificationView::GetPreferredSize() {
253 if (!content_view_) 262 if (!content_view_)
254 return gfx::Size(); 263 return gfx::Size();
255 gfx::Size size = content_view_->GetPreferredSize(); 264 gfx::Size size = content_view_->GetPreferredSize();
256 if (border()) { 265 if (border()) {
257 gfx::Insets border_insets = border()->GetInsets(); 266 gfx::Insets border_insets = border()->GetInsets();
258 size.Enlarge(border_insets.width(), border_insets.height()); 267 size.Enlarge(border_insets.width(), border_insets.height());
259 } 268 }
260 return size; 269 return size;
261 } 270 }
262 271
263 void NotificationView::SetUpView() {
264 // 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
266 // 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
268 // content as needed to provide a large enough click area
269 // (<http://crbug.com/168822> and touch area <http://crbug.com/168856>).
270 AddChildView(MakeContentView());
271 AddChildView(close_button());
272 }
273
274 void NotificationView::ButtonPressed(views::Button* sender, 272 void NotificationView::ButtonPressed(views::Button* sender,
275 const ui::Event& event) { 273 const ui::Event& event) {
276 for (size_t i = 0; i < action_buttons_.size(); ++i) { 274 for (size_t i = 0; i < action_buttons_.size(); ++i) {
277 if (action_buttons_[i] == sender) { 275 if (action_buttons_[i] == sender) {
278 list_delegate()->OnButtonClicked(notification().id, i); 276 list_delegate()->OnButtonClicked(notification_id(), i);
279 return; 277 return;
280 } 278 }
281 } 279 }
282 MessageView::ButtonPressed(sender, event); 280 MessageView::ButtonPressed(sender, event);
283 } 281 }
284 282
285 views::View* NotificationView::MakeContentView() { 283 views::View* NotificationView::MakeContentView(
284 const Notification& notification) {
286 content_view_ = new views::View(); 285 content_view_ = new views::View();
287 content_view_->set_background( 286 content_view_->set_background(
288 views::Background::CreateSolidBackground(kBackgroundColor)); 287 views::Background::CreateSolidBackground(kBackgroundColor));
289 288
290 // The top part of the content view is composed of an icon view on the left 289 // 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 290 // 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 291 // 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 292 // information about the text views, so these are created first and collected
294 // in this vector. 293 // in this vector.
295 std::vector<views::View*> texts; 294 std::vector<views::View*> texts;
296 295
297 // Title if it exists. 296 // Title if it exists.
298 if (!notification().title.empty()) { 297 if (!notification.title().empty()) {
299 views::Label* title = new views::Label(notification().title); 298 views::Label* title = new views::Label(notification.title());
300 title->SetHorizontalAlignment(gfx::ALIGN_LEFT); 299 title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
301 title->SetElideBehavior(views::Label::ELIDE_AT_END); 300 title->SetElideBehavior(views::Label::ELIDE_AT_END);
302 title->SetFont(title->font().DeriveFont(4)); 301 title->SetFont(title->font().DeriveFont(4));
303 title->SetEnabledColor(kTitleColor); 302 title->SetEnabledColor(kTitleColor);
304 title->SetBackgroundColor(kTitleBackgroundColor); 303 title->SetBackgroundColor(kTitleBackgroundColor);
305 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextRightPadding)); 304 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextRightPadding));
306 texts.push_back(title); 305 texts.push_back(title);
307 } 306 }
308 307
309 // Message if appropriate. 308 // Message if appropriate.
310 if (notification().items.size() == 0 && !notification().message.empty()) { 309 if (notification.items().size() == 0 &&
311 views::Label* message = new views::Label(notification().message); 310 !notification.message().empty()) {
311 views::Label* message = new views::Label(notification.message());
312 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); 312 message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
313 message->SetMultiLine(true); 313 message->SetMultiLine(true);
314 message->SetEnabledColor(kMessageColor); 314 message->SetEnabledColor(kMessageColor);
315 message->SetBackgroundColor(kMessageBackgroundColor); 315 message->SetBackgroundColor(kMessageBackgroundColor);
316 message->set_border(MakePadding(0, 0, 3, kTextRightPadding)); 316 message->set_border(MakePadding(0, 0, 3, kTextRightPadding));
317 texts.push_back(message); 317 texts.push_back(message);
318 } 318 }
319 319
320 // List notification items up to a maximum. 320 // List notification items up to a maximum.
321 int items = std::min(notification().items.size(), kNotificationMaximumItems); 321 int items = std::min(notification.items().size(),
322 kNotificationMaximumItems);
322 for (int i = 0; i < items; ++i) { 323 for (int i = 0; i < items; ++i) {
323 ItemView* item = new ItemView(notification().items[i]); 324 ItemView* item = new ItemView(notification.items()[i]);
324 item->set_border(MakePadding(0, 0, 4, kTextRightPadding)); 325 item->set_border(MakePadding(0, 0, 4, kTextRightPadding));
325 texts.push_back(item); 326 texts.push_back(item);
326 } 327 }
327 328
328 // Set up the content view with a fixed-width icon column on the left and a 329 // 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 330 // 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 331 // number of columns and simplify column spanning, padding is applied to each
331 // view within columns instead of through padding columns. 332 // view within columns instead of through padding columns.
332 views::GridLayout* layout = new views::GridLayout(content_view_); 333 views::GridLayout* layout = new views::GridLayout(content_view_);
333 content_view_->SetLayoutManager(layout); 334 content_view_->SetLayoutManager(layout);
334 views::ColumnSet* columns = layout->AddColumnSet(0); 335 views::ColumnSet* columns = layout->AddColumnSet(0);
335 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 336 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
336 0, views::GridLayout::FIXED, 337 0, views::GridLayout::FIXED,
337 kIconColumnWidth + kIconToTextPadding, 338 kIconColumnWidth + kIconToTextPadding,
338 kIconColumnWidth + kIconToTextPadding); 339 kIconColumnWidth + kIconToTextPadding);
339 // Padding + icon + padding. 340 // Padding + icon + padding.
340 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 341 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
341 100, views::GridLayout::USE_PREF, 0, 0); 342 100, views::GridLayout::USE_PREF, 0, 0);
342 // Text + padding. 343 // Text + padding.
343 344
344 // Create the first row and its icon view, which spans all the text views 345 // 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. 346 // to its right as well as the padding view below them.
346 layout->StartRow(0, 0); 347 layout->StartRow(0, 0);
347 views::ImageView* icon = new views::ImageView(); 348 views::ImageView* icon = new views::ImageView();
348 icon->SetImageSize(gfx::Size(message_center::kNotificationIconSize, 349 icon->SetImageSize(gfx::Size(message_center::kNotificationIconSize,
349 message_center::kNotificationIconSize)); 350 message_center::kNotificationIconSize));
350 icon->SetImage(notification().primary_icon); 351 icon->SetImage(notification.primary_icon());
351 icon->SetHorizontalAlignment(views::ImageView::LEADING); 352 icon->SetHorizontalAlignment(views::ImageView::LEADING);
352 icon->SetVerticalAlignment(views::ImageView::LEADING); 353 icon->SetVerticalAlignment(views::ImageView::LEADING);
353 icon->set_border(MakePadding(0, 0, 0, kIconToTextPadding)); 354 icon->set_border(MakePadding(0, 0, 0, kIconToTextPadding));
354 layout->AddView(icon, 1, texts.size() + 1); 355 layout->AddView(icon, 1, texts.size() + 1);
355 356
356 // Add the text views, creating rows for them if necessary. 357 // Add the text views, creating rows for them if necessary.
357 for (size_t i = 0; i < texts.size(); ++i) { 358 for (size_t i = 0; i < texts.size(); ++i) {
358 if (i > 0) { 359 if (i > 0) {
359 layout->StartRow(0, 0); 360 layout->StartRow(0, 0);
360 layout->SkipColumns(1); 361 layout->SkipColumns(1);
361 } 362 }
362 layout->AddView(texts[i]); 363 layout->AddView(texts[i]);
363 } 364 }
364 365
365 // Add a text padding row if necessary. This adds some space between the last 366 // 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 367 // 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. 368 // top-justified by expanding vertically to take up any extra space.
368 if (texts.size() == 0) { 369 if (texts.size() == 0) {
369 layout->SkipColumns(1); 370 layout->SkipColumns(1);
370 } else { 371 } else {
371 layout->StartRow(100, 0); 372 layout->StartRow(100, 0);
372 layout->SkipColumns(1); 373 layout->SkipColumns(1);
373 views::View* padding = new views::ImageView(); 374 views::View* padding = new views::ImageView();
374 padding->set_border(MakePadding(kTextBottomPadding, 1, 0, 0)); 375 padding->set_border(MakePadding(kTextBottomPadding, 1, 0, 0));
375 layout->AddView(padding); 376 layout->AddView(padding);
376 } 377 }
377 378
378 // Add an image row if appropriate. 379 // Add an image row if appropriate.
379 if (!notification().image.isNull()) { 380 if (!notification.image().isNull()) {
380 layout->StartRow(0, 0); 381 layout->StartRow(0, 0);
381 views::ImageView* image = new ProportionalImageView(); 382 views::ImageView* image = new ProportionalImageView();
382 image->SetImageSize(notification().image.size()); 383 image->SetImageSize(notification.image().size());
383 image->SetImage(notification().image); 384 image->SetImage(notification.image());
384 image->SetHorizontalAlignment(views::ImageView::CENTER); 385 image->SetHorizontalAlignment(views::ImageView::CENTER);
385 image->SetVerticalAlignment(views::ImageView::LEADING); 386 image->SetVerticalAlignment(views::ImageView::LEADING);
386 layout->AddView(image, 2, 1); 387 layout->AddView(image, 2, 1);
387 } 388 }
388 389
389 // Add action button rows. 390 // Add action button rows.
390 for (size_t i = 0; i < notification().button_titles.size(); ++i) { 391 for (size_t i = 0; i < notification.buttons().size(); ++i) {
391 views::View* separator = new views::View(); 392 views::View* separator = new views::View();
392 separator->set_background(MakeBackground(kButtonSeparatorColor)); 393 separator->set_background(MakeBackground(kButtonSeparatorColor));
393 layout->StartRow(0, 0); 394 layout->StartRow(0, 0);
394 layout->AddView(separator, 2, 1, 395 layout->AddView(separator, 2, 1,
395 views::GridLayout::FILL, views::GridLayout::FILL, 0, 1); 396 views::GridLayout::FILL, views::GridLayout::FILL, 0, 1);
396 NotificationButton* button = new NotificationButton(this); 397 NotificationButton* button = new NotificationButton(this);
397 button->SetTitle(notification().button_titles[i]); 398 ButtonInfo button_info = notification.buttons()[i];
398 button->SetIcon(notification().button_icons[i]); 399 button->SetTitle(button_info.title);
400 button->SetIcon(button_info.icon);
399 action_buttons_.push_back(button); 401 action_buttons_.push_back(button);
400 layout->StartRow(0, 0); 402 layout->StartRow(0, 0);
401 layout->AddView(button, 2, 1, 403 layout->AddView(button, 2, 1,
402 views::GridLayout::FILL, views::GridLayout::FILL, 0, 40); 404 views::GridLayout::FILL, views::GridLayout::FILL, 0, 40);
403 } 405 }
404 406
405 return content_view_; 407 return content_view_;
406 } 408 }
407 409
408 } // namespace message_center 410 } // namespace message_center
OLDNEW
« no previous file with comments | « ui/message_center/notification_view.h ('k') | ui/notifications/OWNERS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698