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

Side by Side Diff: ui/message_center/views/notification_view_md.cc

Issue 2942143002: Add progress notification support to new-style notification. (Closed)
Patch Set: Resolve review comments. Created 3 years, 6 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
« no previous file with comments | « ui/message_center/views/notification_view_md.h ('k') | ui/views/controls/progress_bar.h » ('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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/views/notification_view_md.h" 5 #include "ui/message_center/views/notification_view_md.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "ui/base/cursor/cursor.h" 10 #include "ui/base/cursor/cursor.h"
11 #include "ui/base/l10n/l10n_util.h" 11 #include "ui/base/l10n/l10n_util.h"
12 #include "ui/gfx/canvas.h"
12 #include "ui/gfx/geometry/size.h" 13 #include "ui/gfx/geometry/size.h"
13 #include "ui/gfx/image/image_skia_operations.h" 14 #include "ui/gfx/image/image_skia_operations.h"
14 #include "ui/gfx/paint_vector_icon.h" 15 #include "ui/gfx/paint_vector_icon.h"
15 #include "ui/gfx/skia_util.h" 16 #include "ui/gfx/skia_util.h"
16 #include "ui/gfx/text_elider.h" 17 #include "ui/gfx/text_elider.h"
17 #include "ui/message_center/message_center.h" 18 #include "ui/message_center/message_center.h"
18 #include "ui/message_center/message_center_style.h" 19 #include "ui/message_center/message_center_style.h"
19 #include "ui/message_center/notification.h" 20 #include "ui/message_center/notification.h"
20 #include "ui/message_center/notification_types.h" 21 #include "ui/message_center/notification_types.h"
21 #include "ui/message_center/vector_icons.h" 22 #include "ui/message_center/vector_icons.h"
22 #include "ui/message_center/views/bounded_label.h" 23 #include "ui/message_center/views/bounded_label.h"
23 #include "ui/message_center/views/constants.h" 24 #include "ui/message_center/views/constants.h"
24 #include "ui/message_center/views/message_center_controller.h" 25 #include "ui/message_center/views/message_center_controller.h"
25 #include "ui/message_center/views/notification_header_view.h" 26 #include "ui/message_center/views/notification_header_view.h"
26 #include "ui/message_center/views/padded_button.h" 27 #include "ui/message_center/views/padded_button.h"
27 #include "ui/message_center/views/proportional_image_view.h" 28 #include "ui/message_center/views/proportional_image_view.h"
28 #include "ui/strings/grit/ui_strings.h" 29 #include "ui/strings/grit/ui_strings.h"
29 #include "ui/views/background.h" 30 #include "ui/views/background.h"
30 #include "ui/views/border.h" 31 #include "ui/views/border.h"
31 #include "ui/views/controls/button/label_button.h" 32 #include "ui/views/controls/button/label_button.h"
32 #include "ui/views/controls/image_view.h" 33 #include "ui/views/controls/image_view.h"
33 #include "ui/views/controls/label.h" 34 #include "ui/views/controls/label.h"
35 #include "ui/views/controls/progress_bar.h"
34 #include "ui/views/focus/focus_manager.h" 36 #include "ui/views/focus/focus_manager.h"
35 #include "ui/views/layout/box_layout.h" 37 #include "ui/views/layout/box_layout.h"
36 #include "ui/views/layout/fill_layout.h" 38 #include "ui/views/layout/fill_layout.h"
37 #include "ui/views/native_cursor.h" 39 #include "ui/views/native_cursor.h"
38 #include "ui/views/view_targeter.h" 40 #include "ui/views/view_targeter.h"
39 #include "ui/views/widget/widget.h" 41 #include "ui/views/widget/widget.h"
40 42
41 namespace message_center { 43 namespace message_center {
42 44
43 namespace { 45 namespace {
44 46
45 // Dimensions. 47 // Dimensions.
46 constexpr gfx::Insets kContentRowPadding(4, 12, 12, 12); 48 constexpr gfx::Insets kContentRowPadding(4, 12, 12, 12);
47 constexpr gfx::Insets kActionsRowPadding(8, 8, 8, 8); 49 constexpr gfx::Insets kActionsRowPadding(8, 8, 8, 8);
48 constexpr int kActionsRowHorizontalSpacing = 8; 50 constexpr int kActionsRowHorizontalSpacing = 8;
49 constexpr gfx::Insets kImageContainerPadding(0, 12, 12, 12); 51 constexpr gfx::Insets kImageContainerPadding(0, 12, 12, 12);
50 52
51 // Foreground of small icon image. 53 // Foreground of small icon image.
52 constexpr SkColor kSmallImageBackgroundColor = SK_ColorWHITE; 54 constexpr SkColor kSmallImageBackgroundColor = SK_ColorWHITE;
53 // Background of small icon image. 55 // Background of small icon image.
54 const SkColor kSmallImageColor = SkColorSetRGB(0x43, 0x43, 0x43); 56 const SkColor kSmallImageColor = SkColorSetRGB(0x43, 0x43, 0x43);
55 // Background of inline actions area. 57 // Background of inline actions area.
56 const SkColor kActionsRowBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee); 58 const SkColor kActionsRowBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee);
57 59
58 // Max number of lines for message_view_. 60 // Max number of lines for message_view_.
59 constexpr int kMaxLinesForMessageView = 1; 61 constexpr int kMaxLinesForMessageView = 1;
60 constexpr int kMaxLinesForExpandedMessageView = 4; 62 constexpr int kMaxLinesForExpandedMessageView = 4;
61 63
64 constexpr int kCompactTitleMessageViewSpacing = 12;
65
66 constexpr int kProgressBarHeight = 4;
67
62 const gfx::ImageSkia CreateSolidColorImage(int width, 68 const gfx::ImageSkia CreateSolidColorImage(int width,
63 int height, 69 int height,
64 SkColor color) { 70 SkColor color) {
65 SkBitmap bitmap; 71 SkBitmap bitmap;
66 bitmap.allocN32Pixels(width, height); 72 bitmap.allocN32Pixels(width, height);
67 bitmap.eraseColor(color); 73 bitmap.eraseColor(color);
68 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap); 74 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
69 } 75 }
70 76
71 // Take the alpha channel of icon, mask it with the foreground, 77 // Take the alpha channel of icon, mask it with the foreground,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 views::Label* message = new views::Label(item.message); 124 views::Label* message = new views::Label(item.message);
119 message->set_collapse_when_hidden(true); 125 message->set_collapse_when_hidden(true);
120 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); 126 message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
121 message->SetEnabledColor(message_center::kDimTextColor); 127 message->SetEnabledColor(message_center::kDimTextColor);
122 message->SetBackgroundColor(message_center::kDimTextBackgroundColor); 128 message->SetBackgroundColor(message_center::kDimTextBackgroundColor);
123 AddChildView(message); 129 AddChildView(message);
124 } 130 }
125 131
126 ItemView::~ItemView() {} 132 ItemView::~ItemView() {}
127 133
134 // CompactTitleMessageView /////////////////////////////////////////////////////
135
136 // CompactTitleMessageView shows notification title and message in a single
137 // line. This view is used for NOTIFICATION_TYPE_PROGRESS.
138 class CompactTitleMessageView : public views::View {
139 public:
140 explicit CompactTitleMessageView();
141 ~CompactTitleMessageView() override;
142
143 void OnPaint(gfx::Canvas* canvas) override;
144
145 void set_title(const base::string16& title) { title_ = title; }
146 void set_message(const base::string16& message) { message_ = message; }
147
148 private:
149 DISALLOW_COPY_AND_ASSIGN(CompactTitleMessageView);
150
151 base::string16 title_;
152 base::string16 message_;
153
154 views::Label* title_view_ = nullptr;
155 views::Label* message_view_ = nullptr;
156 };
157
158 CompactTitleMessageView::~CompactTitleMessageView() {}
159
160 CompactTitleMessageView::CompactTitleMessageView() {
161 SetLayoutManager(new views::FillLayout());
162
163 const gfx::FontList& font_list = views::Label().font_list().Derive(
164 1, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL);
165
166 title_view_ = new views::Label();
167 title_view_->SetFontList(font_list);
168 title_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
169 title_view_->SetEnabledColor(message_center::kRegularTextColor);
170 AddChildView(title_view_);
171
172 message_view_ = new views::Label();
173 message_view_->SetFontList(font_list);
174 message_view_->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
175 message_view_->SetEnabledColor(message_center::kDimTextColor);
176 AddChildView(message_view_);
177 }
178
179 void CompactTitleMessageView::OnPaint(gfx::Canvas* canvas) {
180 base::string16 title = title_;
181 base::string16 message = message_;
182
183 const gfx::FontList& font_list = views::Label().font_list().Derive(
184 1, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL);
185
186 // Elides title and message. The behavior is based on Android's one.
187 // * If the title is too long, only the title is shown.
188 // * If the message is too long, the full content of the title is shown,
189 // kCompactTitleMessageViewSpacing is added between them, and the elided
190 // message is shown.
191 // * If they are short enough, the title is left-aligned and the message is
192 // right-aligned.
193 const int original_title_width =
194 gfx::Canvas::GetStringWidthF(title, font_list);
195 if (original_title_width >= width())
196 message.clear();
197 title = gfx::ElideText(title, font_list, width(), gfx::ELIDE_TAIL);
198 const int title_width = gfx::Canvas::GetStringWidthF(title, font_list);
199 const int message_width =
200 std::max(0, width() - title_width - kCompactTitleMessageViewSpacing);
201 message = gfx::ElideText(message, font_list, message_width, gfx::ELIDE_TAIL);
202
203 title_view_->SetText(title);
204 message_view_->SetText(message);
205
206 views::View::OnPaint(canvas);
207 }
208
128 } // anonymous namespace 209 } // anonymous namespace
129 210
130 // //////////////////////////////////////////////////////////// 211 // ////////////////////////////////////////////////////////////
131 // NotificationViewMD 212 // NotificationViewMD
132 // //////////////////////////////////////////////////////////// 213 // ////////////////////////////////////////////////////////////
133 214
134 views::View* NotificationViewMD::TargetForRect(views::View* root, 215 views::View* NotificationViewMD::TargetForRect(views::View* root,
135 const gfx::Rect& rect) { 216 const gfx::Rect& rect) {
136 CHECK_EQ(root, this); 217 CHECK_EQ(root, this);
137 218
(...skipping 18 matching lines...) Expand all
156 gfx::Point point_in_child = point; 237 gfx::Point point_in_child = point;
157 ConvertPointToTarget(this, buttons[i], &point_in_child); 238 ConvertPointToTarget(this, buttons[i], &point_in_child);
158 if (buttons[i]->HitTestPoint(point_in_child)) 239 if (buttons[i]->HitTestPoint(point_in_child))
159 return buttons[i]->GetEventHandlerForPoint(point_in_child); 240 return buttons[i]->GetEventHandlerForPoint(point_in_child);
160 } 241 }
161 242
162 return root; 243 return root;
163 } 244 }
164 245
165 void NotificationViewMD::CreateOrUpdateViews(const Notification& notification) { 246 void NotificationViewMD::CreateOrUpdateViews(const Notification& notification) {
247 right_content_->SetVisible(notification.type() !=
fukino 2017/06/22 00:27:10 I think you can check the notification type in Cre
tetsui 2017/06/22 02:09:23 Done.
248 NOTIFICATION_TYPE_PROGRESS &&
249 notification.type() != NOTIFICATION_TYPE_MULTIPLE);
166 CreateOrUpdateContextTitleView(notification); 250 CreateOrUpdateContextTitleView(notification);
167 CreateOrUpdateTitleView(notification); 251 CreateOrUpdateTitleView(notification);
168 CreateOrUpdateMessageView(notification); 252 CreateOrUpdateMessageView(notification);
253 CreateOrUpdateCompactTitleMessageView(notification);
169 CreateOrUpdateProgressBarView(notification); 254 CreateOrUpdateProgressBarView(notification);
170 CreateOrUpdateListItemViews(notification); 255 CreateOrUpdateListItemViews(notification);
171 CreateOrUpdateIconView(notification); 256 CreateOrUpdateIconView(notification);
172 CreateOrUpdateSmallIconView(notification); 257 CreateOrUpdateSmallIconView(notification);
173 CreateOrUpdateImageView(notification); 258 CreateOrUpdateImageView(notification);
174 CreateOrUpdateActionButtonViews(notification); 259 CreateOrUpdateActionButtonViews(notification);
175 CreateOrUpdateCloseButtonView(notification); 260 CreateOrUpdateCloseButtonView(notification);
176 CreateOrUpdateSettingsButtonView(notification); 261 CreateOrUpdateSettingsButtonView(notification);
177 UpdateViewForExpandedState(expanded_); 262 UpdateViewForExpandedState(expanded_);
178 } 263 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 header_row_->close_button()->RequestFocus(); 417 header_row_->close_button()->RequestFocus();
333 } 418 }
334 419
335 void NotificationViewMD::CreateOrUpdateContextTitleView( 420 void NotificationViewMD::CreateOrUpdateContextTitleView(
336 const Notification& notification) { 421 const Notification& notification) {
337 header_row_->SetAppName(notification.display_source()); 422 header_row_->SetAppName(notification.display_source());
338 } 423 }
339 424
340 void NotificationViewMD::CreateOrUpdateTitleView( 425 void NotificationViewMD::CreateOrUpdateTitleView(
341 const Notification& notification) { 426 const Notification& notification) {
427 if (notification.type() == NOTIFICATION_TYPE_PROGRESS) {
428 left_content_->RemoveChildView(title_view_);
429 title_view_ = nullptr;
430 return;
431 }
342 const gfx::FontList& font_list = views::Label().font_list().Derive( 432 const gfx::FontList& font_list = views::Label().font_list().Derive(
343 1, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL); 433 1, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL);
344 434
345 int title_character_limit = 435 int title_character_limit =
346 kNotificationWidth * kMaxTitleLines / kMinPixelsPerTitleCharacter; 436 kNotificationWidth * kMaxTitleLines / kMinPixelsPerTitleCharacter;
347 437
348 base::string16 title = gfx::TruncateString( 438 base::string16 title = gfx::TruncateString(
349 notification.title(), title_character_limit, gfx::WORD_BREAK); 439 notification.title(), title_character_limit, gfx::WORD_BREAK);
350 if (!title_view_) { 440 if (!title_view_) {
351 title_view_ = new views::Label(title); 441 title_view_ = new views::Label(title);
352 title_view_->SetFontList(font_list); 442 title_view_->SetFontList(font_list);
353 title_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 443 title_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
354 title_view_->SetEnabledColor(message_center::kRegularTextColor); 444 title_view_->SetEnabledColor(message_center::kRegularTextColor);
355 left_content_->AddChildView(title_view_); 445 left_content_->AddChildView(title_view_);
356 } else { 446 } else {
357 title_view_->SetText(title); 447 title_view_->SetText(title);
358 } 448 }
359 } 449 }
360 450
361 void NotificationViewMD::CreateOrUpdateMessageView( 451 void NotificationViewMD::CreateOrUpdateMessageView(
362 const Notification& notification) { 452 const Notification& notification) {
363 if (notification.message().empty()) { 453 if (notification.type() == NOTIFICATION_TYPE_PROGRESS ||
364 // Deletion will also remove |context_message_view_| from its parent. 454 notification.message().empty()) {
455 // Deletion will also remove |message_view_| from its parent.
365 delete message_view_; 456 delete message_view_;
366 message_view_ = nullptr; 457 message_view_ = nullptr;
367 return; 458 return;
368 } 459 }
369 460
370 base::string16 text = gfx::TruncateString( 461 base::string16 text = gfx::TruncateString(
371 notification.message(), kMessageCharacterLimit, gfx::WORD_BREAK); 462 notification.message(), kMessageCharacterLimit, gfx::WORD_BREAK);
372 463
373 const gfx::FontList& font_list = views::Label().font_list().Derive( 464 const gfx::FontList& font_list = views::Label().font_list().Derive(
374 1, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL); 465 1, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL);
375 466
376 if (!message_view_) { 467 if (!message_view_) {
377 message_view_ = new BoundedLabel(text, font_list); 468 message_view_ = new BoundedLabel(text, font_list);
378 message_view_->SetLineLimit(kMaxLinesForMessageView); 469 message_view_->SetLineLimit(kMaxLinesForMessageView);
379 message_view_->SetColors(message_center::kDimTextColor, 470 message_view_->SetColors(message_center::kDimTextColor,
380 kContextTextBackgroundColor); 471 kContextTextBackgroundColor);
381 left_content_->AddChildView(message_view_); 472 left_content_->AddChildView(message_view_);
382 } else { 473 } else {
383 message_view_->SetText(text); 474 message_view_->SetText(text);
384 } 475 }
385 476
386 message_view_->SetVisible(notification.items().empty()); 477 message_view_->SetVisible(notification.items().empty());
387 } 478 }
388 479
480 void NotificationViewMD::CreateOrUpdateCompactTitleMessageView(
481 const Notification& notification) {
482 if (notification.type() != NOTIFICATION_TYPE_PROGRESS) {
483 left_content_->RemoveChildView(compact_title_message_view_);
484 compact_title_message_view_ = nullptr;
485 return;
486 }
487 if (!compact_title_message_view_) {
488 compact_title_message_view_ = new CompactTitleMessageView();
489 left_content_->AddChildView(compact_title_message_view_);
490 }
491
492 compact_title_message_view_->set_title(notification.title());
493 compact_title_message_view_->set_message(notification.message());
494 left_content_->InvalidateLayout();
495 }
496
389 void NotificationViewMD::CreateOrUpdateProgressBarView( 497 void NotificationViewMD::CreateOrUpdateProgressBarView(
390 const Notification& notification) { 498 const Notification& notification) {
391 // TODO(yoshiki): Implement this. 499 if (notification.type() != NOTIFICATION_TYPE_PROGRESS) {
500 left_content_->RemoveChildView(progress_bar_view_);
501 progress_bar_view_ = nullptr;
502 return;
503 }
504
505 DCHECK(left_content_);
506
507 if (!progress_bar_view_) {
508 progress_bar_view_ = new views::ProgressBar(kProgressBarHeight,
509 /* allow_round_corner */ false);
510 progress_bar_view_->SetBorder(views::CreateEmptyBorder(
511 message_center::kProgressBarTopPadding, 0, 0, 0));
512 left_content_->AddChildView(progress_bar_view_);
513 }
514
515 progress_bar_view_->SetValue(notification.progress() / 100.0);
516 progress_bar_view_->SetVisible(notification.items().empty());
392 } 517 }
393 518
394 void NotificationViewMD::CreateOrUpdateListItemViews( 519 void NotificationViewMD::CreateOrUpdateListItemViews(
395 const Notification& notification) { 520 const Notification& notification) {
396 for (auto* item_view : item_views_) 521 for (auto* item_view : item_views_)
397 delete item_view; 522 delete item_view;
398 item_views_.clear(); 523 item_views_.clear();
399 524
400 const std::vector<NotificationItem>& items = notification.items(); 525 const std::vector<NotificationItem>& items = notification.items();
401 526
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 header_row_->expand_button()->HasFocus()) || 705 header_row_->expand_button()->HasFocus()) ||
581 (header_row_->IsCloseButtonEnabled() && 706 (header_row_->IsCloseButtonEnabled() &&
582 header_row_->close_button()->HasFocus()) || 707 header_row_->close_button()->HasFocus()) ||
583 (header_row_->IsSettingsButtonEnabled() && 708 (header_row_->IsSettingsButtonEnabled() &&
584 header_row_->settings_button()->HasFocus()); 709 header_row_->settings_button()->HasFocus());
585 710
586 header_row_->SetControlButtonsVisible(target_visibility); 711 header_row_->SetControlButtonsVisible(target_visibility);
587 } 712 }
588 713
589 } // namespace message_center 714 } // namespace message_center
OLDNEW
« no previous file with comments | « ui/message_center/views/notification_view_md.h ('k') | ui/views/controls/progress_bar.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698