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