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

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

Issue 2969603003: Implement new-style image notification resizing. (Closed)
Patch Set: Adjust height to follow the mock. Created 3 years, 5 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') | no next file » | 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"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "ui/views/widget/widget.h" 42 #include "ui/views/widget/widget.h"
43 43
44 namespace message_center { 44 namespace message_center {
45 45
46 namespace { 46 namespace {
47 47
48 // Dimensions. 48 // Dimensions.
49 constexpr gfx::Insets kContentRowPadding(4, 12, 12, 12); 49 constexpr gfx::Insets kContentRowPadding(4, 12, 12, 12);
50 constexpr gfx::Insets kActionsRowPadding(8, 8, 8, 8); 50 constexpr gfx::Insets kActionsRowPadding(8, 8, 8, 8);
51 constexpr int kActionsRowHorizontalSpacing = 8; 51 constexpr int kActionsRowHorizontalSpacing = 8;
52 constexpr gfx::Insets kImageContainerPadding(0, 12, 12, 12);
53 constexpr gfx::Insets kActionButtonPadding(0, 12, 0, 12); 52 constexpr gfx::Insets kActionButtonPadding(0, 12, 0, 12);
54 constexpr gfx::Size kActionButtonMinSize(88, 32); 53 constexpr gfx::Size kActionButtonMinSize(88, 32);
54 constexpr gfx::Insets kLargeImageContainerPadding(0, 12, 12, 12);
55 constexpr gfx::Size kLargeImageMinSize(328, 0);
56 constexpr gfx::Size kLargeImageMaxSize(328, 218);
tetsui 2017/07/03 03:51:25 In new-style notification mock, the notification w
55 57
56 // Foreground of small icon image. 58 // Foreground of small icon image.
57 constexpr SkColor kSmallImageBackgroundColor = SK_ColorWHITE; 59 constexpr SkColor kSmallImageBackgroundColor = SK_ColorWHITE;
58 // Background of small icon image. 60 // Background of small icon image.
59 const SkColor kSmallImageColor = SkColorSetRGB(0x43, 0x43, 0x43); 61 const SkColor kSmallImageColor = SkColorSetRGB(0x43, 0x43, 0x43);
60 // Background of inline actions area. 62 // Background of inline actions area.
61 const SkColor kActionsRowBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee); 63 const SkColor kActionsRowBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee);
62 // Base ink drop color of action buttons. 64 // Base ink drop color of action buttons.
63 const SkColor kActionButtonInkDropBaseColor = SkColorSetRGB(0x0, 0x0, 0x0); 65 const SkColor kActionButtonInkDropBaseColor = SkColorSetRGB(0x0, 0x0, 0x0);
64 // Ripple ink drop opacity of action buttons. 66 // Ripple ink drop opacity of action buttons.
65 const float kActionButtonInkDropRippleVisibleOpacity = 0.08f; 67 const float kActionButtonInkDropRippleVisibleOpacity = 0.08f;
66 // Highlight (hover) ink drop opacity of action buttons. 68 // Highlight (hover) ink drop opacity of action buttons.
67 const float kActionButtonInkDropHighlightVisibleOpacity = 0.08f; 69 const float kActionButtonInkDropHighlightVisibleOpacity = 0.08f;
68 // Text color of action button. 70 // Text color of action button.
69 const SkColor kActionButtonTextColor = SkColorSetRGB(0x33, 0x67, 0xD6); 71 const SkColor kActionButtonTextColor = SkColorSetRGB(0x33, 0x67, 0xD6);
72 // Background color of the large image.
73 const SkColor kLargeImageBackgroundColor = SkColorSetRGB(0xf5, 0xf5, 0xf5);
70 74
71 // Max number of lines for message_view_. 75 // Max number of lines for message_view_.
72 constexpr int kMaxLinesForMessageView = 1; 76 constexpr int kMaxLinesForMessageView = 1;
73 constexpr int kMaxLinesForExpandedMessageView = 4; 77 constexpr int kMaxLinesForExpandedMessageView = 4;
74 78
75 constexpr int kListNotificationOverflowIndicatorSpacing = 4; 79 constexpr int kListNotificationOverflowIndicatorSpacing = 4;
76 constexpr int kCompactTitleMessageViewSpacing = 12; 80 constexpr int kCompactTitleMessageViewSpacing = 12;
77 81
78 constexpr int kProgressBarHeight = 4; 82 constexpr int kProgressBarHeight = 4;
79 83
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 NotificationButtonMD::~NotificationButtonMD() = default; 309 NotificationButtonMD::~NotificationButtonMD() = default;
306 310
307 std::unique_ptr<views::InkDropHighlight> 311 std::unique_ptr<views::InkDropHighlight>
308 NotificationButtonMD::CreateInkDropHighlight() const { 312 NotificationButtonMD::CreateInkDropHighlight() const {
309 std::unique_ptr<views::InkDropHighlight> highlight = 313 std::unique_ptr<views::InkDropHighlight> highlight =
310 views::LabelButton::CreateInkDropHighlight(); 314 views::LabelButton::CreateInkDropHighlight();
311 highlight->set_visible_opacity(kActionButtonInkDropHighlightVisibleOpacity); 315 highlight->set_visible_opacity(kActionButtonInkDropHighlightVisibleOpacity);
312 return highlight; 316 return highlight;
313 } 317 }
314 318
319 // LargeImageView //////////////////////////////////////////////////////////////
320
321 class LargeImageView : public views::View {
322 public:
323 explicit LargeImageView();
324 ~LargeImageView() override;
325
326 void SetImage(const gfx::ImageSkia& image);
327
328 void OnPaint(gfx::Canvas* canvas) override;
329 const char* GetClassName() const override;
330
331 views::View* container() { return container_; }
332
333 private:
334 gfx::Size GetResizedImageSize();
335
336 views::View* container_ = nullptr;
yoshiki 2017/07/28 06:13:03 nit: please add a comment about how the container
tetsui 2017/07/28 06:38:45 Done.
337 gfx::ImageSkia image_;
338 };
yoshiki 2017/07/28 06:13:03 Please add DISALLOW_COPY_AND_ASSIGN. This class sh
tetsui 2017/07/28 06:38:45 Done.
339
340 LargeImageView::LargeImageView() {
341 SetBackground(views::CreateSolidBackground(kLargeImageBackgroundColor));
342 container_ = new views::View;
343 container_->SetLayoutManager(new views::FillLayout());
344 container_->SetBorder(views::CreateEmptyBorder(kLargeImageContainerPadding));
345 container_->SetBackground(
346 views::CreateSolidBackground(message_center::kImageBackgroundColor));
347 container_->AddChildView(this);
348 }
349
350 LargeImageView::~LargeImageView() = default;
351
352 void LargeImageView::SetImage(const gfx::ImageSkia& image) {
353 image_ = image;
354 gfx::Size preferred_size = GetResizedImageSize();
355 preferred_size.SetToMax(kLargeImageMinSize);
356 preferred_size.SetToMin(kLargeImageMaxSize);
357 SetPreferredSize(preferred_size);
358 SchedulePaint();
359 Layout();
360 }
361
362 void LargeImageView::OnPaint(gfx::Canvas* canvas) {
363 views::View::OnPaint(canvas);
364
365 gfx::Size resized_size = GetResizedImageSize();
366 gfx::Size drawn_size = resized_size;
367 drawn_size.SetToMin(kLargeImageMaxSize);
368 gfx::Rect drawn_bounds = GetContentsBounds();
369 drawn_bounds.ClampToCenteredSize(drawn_size);
370
371 gfx::ImageSkia resized_image = gfx::ImageSkiaOperations::CreateResizedImage(
372 image_, skia::ImageOperations::RESIZE_BEST, resized_size);
373
374 // Cut off the overflown part.
375 gfx::ImageSkia drawn_image = gfx::ImageSkiaOperations::ExtractSubset(
376 resized_image, gfx::Rect(drawn_size));
377
378 canvas->DrawImageInt(drawn_image, drawn_bounds.x(), drawn_bounds.y());
379 }
380
381 const char* LargeImageView::GetClassName() const {
382 return "LargeImageView";
383 }
384
385 // Returns expected size of the image right after resizing.
386 // The GetResizedImageSize().width() <= kLargeImageMaxSize.width() holds, but
387 // GetResizedImageSize().height() may be larger than kLargeImageMaxSize.height()
388 // In this case, the overflown part will be just cutted off from the view.
389 gfx::Size LargeImageView::GetResizedImageSize() {
390 gfx::Size original_size = image_.size();
391 if (original_size.width() <= kLargeImageMaxSize.width()) {
392 return image_.size();
393 } else {
yoshiki 2017/07/28 06:13:03 optional: I prefer the following style since this
tetsui 2017/07/28 06:38:45 Done.
394 const double proportion =
395 original_size.height() / static_cast<double>(original_size.width());
396 gfx::Size resized_size;
397 resized_size.SetSize(kLargeImageMaxSize.width(),
398 kLargeImageMaxSize.width() * proportion);
399 return resized_size;
400 }
401 }
402
315 } // anonymous namespace 403 } // anonymous namespace
316 404
317 // //////////////////////////////////////////////////////////// 405 // ////////////////////////////////////////////////////////////
318 // NotificationViewMD 406 // NotificationViewMD
319 // //////////////////////////////////////////////////////////// 407 // ////////////////////////////////////////////////////////////
320 408
321 views::View* NotificationViewMD::TargetForRect(views::View* root, 409 views::View* NotificationViewMD::TargetForRect(views::View* root,
322 const gfx::Rect& rect) { 410 const gfx::Rect& rect) {
323 CHECK_EQ(root, this); 411 CHECK_EQ(root, this);
324 412
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 item_views_.back()->SetRemainingCount(items.size() - item_views_.size()); 730 item_views_.back()->SetRemainingCount(items.size() - item_views_.size());
643 731
644 // Needed when CreateOrUpdateViews is called for update. 732 // Needed when CreateOrUpdateViews is called for update.
645 left_content_->InvalidateLayout(); 733 left_content_->InvalidateLayout();
646 } 734 }
647 } 735 }
648 736
649 void NotificationViewMD::CreateOrUpdateIconView( 737 void NotificationViewMD::CreateOrUpdateIconView(
650 const Notification& notification) { 738 const Notification& notification) {
651 if (notification.type() == NOTIFICATION_TYPE_PROGRESS || 739 if (notification.type() == NOTIFICATION_TYPE_PROGRESS ||
652 notification.type() == NOTIFICATION_TYPE_MULTIPLE) { 740 notification.type() == NOTIFICATION_TYPE_MULTIPLE ||
741 notification.type() == NOTIFICATION_TYPE_IMAGE) {
653 right_content_->RemoveChildView(icon_view_); 742 right_content_->RemoveChildView(icon_view_);
654 icon_view_ = nullptr; 743 icon_view_ = nullptr;
655 return; 744 return;
656 } 745 }
657 746
658 gfx::Size image_view_size(30, 30); 747 gfx::Size image_view_size(30, 30);
659 if (!icon_view_) { 748 if (!icon_view_) {
660 icon_view_ = new ProportionalImageView(image_view_size); 749 icon_view_ = new ProportionalImageView(image_view_size);
661 right_content_->AddChildView(icon_view_); 750 right_content_->AddChildView(icon_view_);
662 } 751 }
663 752
664 gfx::ImageSkia icon = notification.icon().AsImageSkia(); 753 gfx::ImageSkia icon = notification.icon().AsImageSkia();
665 icon_view_->SetImage(icon, icon.size()); 754 icon_view_->SetImage(icon, icon.size());
666 } 755 }
667 756
668 void NotificationViewMD::CreateOrUpdateSmallIconView( 757 void NotificationViewMD::CreateOrUpdateSmallIconView(
669 const Notification& notification) { 758 const Notification& notification) {
670 gfx::ImageSkia icon = 759 gfx::ImageSkia icon =
671 notification.small_image().IsEmpty() 760 notification.small_image().IsEmpty()
672 ? GetProductIcon() 761 ? GetProductIcon()
673 : GetMaskedIcon(notification.small_image().AsImageSkia()); 762 : GetMaskedIcon(notification.small_image().AsImageSkia());
674 header_row_->SetAppIcon(icon); 763 header_row_->SetAppIcon(icon);
675 } 764 }
676 765
677 void NotificationViewMD::CreateOrUpdateImageView( 766 void NotificationViewMD::CreateOrUpdateImageView(
678 const Notification& notification) { 767 const Notification& notification) {
679 // |image_view_| is the view representing the area covered by the
680 // notification's image, including background and border. Its size can be
681 // specified in advance and images will be scaled to fit including a border if
682 // necessary.
683 if (notification.image().IsEmpty()) { 768 if (notification.image().IsEmpty()) {
684 if (image_container_) { 769 if (image_view_) {
685 DCHECK(image_view_); 770 RemoveChildView(image_view_->container());
686 771 image_view_ = nullptr;
687 left_content_->RemoveChildView(image_container_);
688 image_container_ = NULL;
689 image_view_ = NULL;
690 } else {
691 DCHECK(!image_view_);
692 } 772 }
693 return; 773 return;
694 } 774 }
695 775
696 gfx::Size ideal_size(kNotificationPreferredImageWidth, 776 if (!image_view_) {
697 kNotificationPreferredImageHeight); 777 image_view_ = new LargeImageView();
698
699 if (!image_container_) {
700 image_container_ = new views::View();
701 image_container_->SetLayoutManager(new views::FillLayout());
702 image_container_->SetBorder(
703 views::CreateEmptyBorder(kImageContainerPadding));
704 image_container_->SetBackground(
705 views::CreateSolidBackground(message_center::kImageBackgroundColor));
706
707 DCHECK(!image_view_);
708 image_view_ = new message_center::ProportionalImageView(ideal_size);
709 image_container_->AddChildView(image_view_);
710 // Insert the created image container just after the |content_row_|. 778 // Insert the created image container just after the |content_row_|.
711 AddChildViewAt(image_container_, GetIndexOf(content_row_) + 1); 779 AddChildViewAt(image_view_->container(), GetIndexOf(content_row_) + 1);
712 } 780 }
713 781
714 DCHECK(image_view_); 782 image_view_->SetImage(notification.image().AsImageSkia());
715 image_view_->SetImage(notification.image().AsImageSkia(), ideal_size);
716 } 783 }
717 784
718 void NotificationViewMD::CreateOrUpdateActionButtonViews( 785 void NotificationViewMD::CreateOrUpdateActionButtonViews(
719 const Notification& notification) { 786 const Notification& notification) {
720 std::vector<ButtonInfo> buttons = notification.buttons(); 787 std::vector<ButtonInfo> buttons = notification.buttons();
721 bool new_buttons = action_buttons_.size() != buttons.size(); 788 bool new_buttons = action_buttons_.size() != buttons.size();
722 789
723 if (new_buttons || buttons.size() == 0) { 790 if (new_buttons || buttons.size() == 0) {
724 for (auto* item : action_buttons_) 791 for (auto* item : action_buttons_)
725 delete item; 792 delete item;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 if (controller()) 868 if (controller())
802 controller()->UpdateNotificationSize(notification_id()); 869 controller()->UpdateNotificationSize(notification_id());
803 } 870 }
804 871
805 void NotificationViewMD::UpdateViewForExpandedState(bool expanded) { 872 void NotificationViewMD::UpdateViewForExpandedState(bool expanded) {
806 header_row_->SetExpanded(expanded); 873 header_row_->SetExpanded(expanded);
807 if (message_view_) { 874 if (message_view_) {
808 message_view_->SetLineLimit(expanded ? kMaxLinesForExpandedMessageView 875 message_view_->SetLineLimit(expanded ? kMaxLinesForExpandedMessageView
809 : kMaxLinesForMessageView); 876 : kMaxLinesForMessageView);
810 } 877 }
811 if (image_container_) 878 if (image_view_)
812 image_container_->SetVisible(expanded); 879 image_view_->container()->SetVisible(expanded);
813 actions_row_->SetVisible(expanded && actions_row_->has_children()); 880 actions_row_->SetVisible(expanded && actions_row_->has_children());
814 for (size_t i = 1; i < item_views_.size(); ++i) { 881 for (size_t i = 1; i < item_views_.size(); ++i) {
815 item_views_[i]->SetVisible(expanded); 882 item_views_[i]->SetVisible(expanded);
816 } 883 }
817 if (!item_views_.empty()) { 884 if (!item_views_.empty()) {
818 item_views_.front()->SetRemainingCountVisible(!expanded); 885 item_views_.front()->SetRemainingCountVisible(!expanded);
819 item_views_.back()->SetRemainingCountVisible(expanded); 886 item_views_.back()->SetRemainingCountVisible(expanded);
820 } 887 }
821 } 888 }
822 889
823 void NotificationViewMD::UpdateControlButtonsVisibility() { 890 void NotificationViewMD::UpdateControlButtonsVisibility() {
824 const bool target_visibility = IsMouseHovered() || HasFocus() || 891 const bool target_visibility = IsMouseHovered() || HasFocus() ||
825 (header_row_->IsExpandButtonEnabled() && 892 (header_row_->IsExpandButtonEnabled() &&
826 header_row_->expand_button()->HasFocus()) || 893 header_row_->expand_button()->HasFocus()) ||
827 (header_row_->IsCloseButtonEnabled() && 894 (header_row_->IsCloseButtonEnabled() &&
828 header_row_->close_button()->HasFocus()) || 895 header_row_->close_button()->HasFocus()) ||
829 (header_row_->IsSettingsButtonEnabled() && 896 (header_row_->IsSettingsButtonEnabled() &&
830 header_row_->settings_button()->HasFocus()); 897 header_row_->settings_button()->HasFocus());
831 898
832 header_row_->SetControlButtonsVisible(target_visibility); 899 header_row_->SetControlButtonsVisible(target_visibility);
833 } 900 }
834 901
835 } // namespace message_center 902 } // namespace message_center
OLDNEW
« no previous file with comments | « ui/message_center/views/notification_view_md.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698