Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |