diff options
Diffstat (limited to 'chromium/ui/message_center')
26 files changed, 198 insertions, 250 deletions
diff --git a/chromium/ui/message_center/BUILD.gn b/chromium/ui/message_center/BUILD.gn index ee5189f31b6..0ea28e028eb 100644 --- a/chromium/ui/message_center/BUILD.gn +++ b/chromium/ui/message_center/BUILD.gn @@ -55,12 +55,7 @@ jumbo_component("message_center") { "//ui/resources", ] - configs += [ - "//build/config:precompiled_headers", - - # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - "//build/config/compiler:no_size_t_to_int_warning", - ] + configs += [ "//build/config:precompiled_headers" ] sources = [ "lock_screen/empty_lock_screen_controller.cc", "lock_screen/empty_lock_screen_controller.h", @@ -118,8 +113,6 @@ jumbo_component("message_center") { "views/notification_control_buttons_view.h", "views/notification_header_view.cc", "views/notification_header_view.h", - "views/notification_view.cc", - "views/notification_view.h", "views/notification_view_md.cc", "views/notification_view_md.h", "views/padded_button.cc", @@ -137,6 +130,8 @@ jumbo_component("message_center") { "views/message_view_context_menu_controller.h", "views/notification_menu_model.cc", "views/notification_menu_model.h", + "views/notification_view.cc", + "views/notification_view.h", ] } deps += [ @@ -229,11 +224,13 @@ if (enable_message_center) { "views/bounded_label_unittest.cc", "views/message_popup_collection_unittest.cc", "views/notification_view_md_unittest.cc", - "views/notification_view_unittest.cc", "views/slide_out_controller_unittest.cc", ] if (!is_chromeos) { - sources += [ "views/notification_menu_model_unittest.cc" ] + sources += [ + "views/notification_menu_model_unittest.cc", + "views/notification_view_unittest.cc", + ] } deps += [ # Compositor is needed by message_center_view_unittest.cc and for the diff --git a/chromium/ui/message_center/fake_message_center.cc b/chromium/ui/message_center/fake_message_center.cc index 2d4213c1d51..abd23cb323a 100644 --- a/chromium/ui/message_center/fake_message_center.cc +++ b/chromium/ui/message_center/fake_message_center.cc @@ -89,12 +89,6 @@ void FakeMessageCenter::SetNotificationImage(const std::string& notification_id, const gfx::Image& image) { } -void FakeMessageCenter::SetNotificationButtonIcon( - const std::string& notification_id, - int button_index, - const gfx::Image& image) { -} - void FakeMessageCenter::ClickOnNotification(const std::string& id) { } diff --git a/chromium/ui/message_center/fake_message_center.h b/chromium/ui/message_center/fake_message_center.h index af89a739018..cb884b89102 100644 --- a/chromium/ui/message_center/fake_message_center.h +++ b/chromium/ui/message_center/fake_message_center.h @@ -46,9 +46,6 @@ class FakeMessageCenter : public MessageCenter { void SetNotificationImage(const std::string& notification_id, const gfx::Image& image) override; - void SetNotificationButtonIcon(const std::string& notification_id, - int button_index, - const gfx::Image& image) override; void ClickOnNotification(const std::string& id) override; void ClickOnNotificationButton(const std::string& id, int button_index) override; diff --git a/chromium/ui/message_center/message_center.h b/chromium/ui/message_center/message_center.h index d0a0397d7ca..6f951852559 100644 --- a/chromium/ui/message_center/message_center.h +++ b/chromium/ui/message_center/message_center.h @@ -122,11 +122,6 @@ class MESSAGE_CENTER_EXPORT MessageCenter { virtual void SetNotificationImage(const std::string& notification_id, const gfx::Image& image) = 0; - // Sets the image for the icon of the specific action button. - virtual void SetNotificationButtonIcon(const std::string& notification_id, - int button_index, - const gfx::Image& image) = 0; - // This should be called by UI classes when a notification is clicked to // trigger the notification's delegate callback and also update the message // center observers. diff --git a/chromium/ui/message_center/message_center_impl.cc b/chromium/ui/message_center/message_center_impl.cc index a0765b5ae17..3dd44cb8e2e 100644 --- a/chromium/ui/message_center/message_center_impl.cc +++ b/chromium/ui/message_center/message_center_impl.cc @@ -308,17 +308,6 @@ void MessageCenterImpl::SetNotificationImage(const std::string& notification_id, } } -void MessageCenterImpl::SetNotificationButtonIcon( - const std::string& notification_id, int button_index, - const gfx::Image& image) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (notification_list_->SetNotificationButtonIcon(notification_id, - button_index, image)) { - for (auto& observer : observer_list_) - observer.OnNotificationUpdated(notification_id); - } -} - void MessageCenterImpl::ClickOnNotification(const std::string& id) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (FindVisibleNotificationById(id) == NULL) diff --git a/chromium/ui/message_center/message_center_impl.h b/chromium/ui/message_center/message_center_impl.h index 43fc402d77a..e408402bb4d 100644 --- a/chromium/ui/message_center/message_center_impl.h +++ b/chromium/ui/message_center/message_center_impl.h @@ -65,9 +65,6 @@ class MessageCenterImpl : public MessageCenter, const gfx::Image& image) override; void SetNotificationImage(const std::string& notification_id, const gfx::Image& image) override; - void SetNotificationButtonIcon(const std::string& notification_id, - int button_index, - const gfx::Image& image) override; void ClickOnNotification(const std::string& id) override; void ClickOnNotificationButton(const std::string& id, int button_index) override; diff --git a/chromium/ui/message_center/notification_list.cc b/chromium/ui/message_center/notification_list.cc index 2cadc988b38..bed04243430 100644 --- a/chromium/ui/message_center/notification_list.cc +++ b/chromium/ui/message_center/notification_list.cc @@ -157,16 +157,6 @@ bool NotificationList::SetNotificationImage(const std::string& notification_id, return true; } -bool NotificationList::SetNotificationButtonIcon( - const std::string& notification_id, int button_index, - const gfx::Image& image) { - auto iter = GetNotification(notification_id); - if (iter == notifications_.end()) - return false; - iter->first->SetButtonIcon(button_index, image); - return true; -} - bool NotificationList::HasNotificationOfType(const std::string& id, const NotificationType type) { auto iter = GetNotification(id); diff --git a/chromium/ui/message_center/notification_list.h b/chromium/ui/message_center/notification_list.h index c42bf211f73..bb8a7c50ff2 100644 --- a/chromium/ui/message_center/notification_list.h +++ b/chromium/ui/message_center/notification_list.h @@ -107,11 +107,6 @@ class MESSAGE_CENTER_EXPORT NotificationList { bool SetNotificationImage(const std::string& notification_id, const gfx::Image& image); - // Returns true if the notification and button exist and were updated. - bool SetNotificationButtonIcon(const std::string& notification_id, - int button_index, - const gfx::Image& image); - // Returns true if |id| matches a notification in the list and that // notification's type matches the given type. bool HasNotificationOfType(const std::string& id, diff --git a/chromium/ui/message_center/public/cpp/notification.h b/chromium/ui/message_center/public/cpp/notification.h index 7ec1310f2c8..f4afa82b7c0 100644 --- a/chromium/ui/message_center/public/cpp/notification.h +++ b/chromium/ui/message_center/public/cpp/notification.h @@ -65,7 +65,8 @@ struct MESSAGE_CENTER_PUBLIC_EXPORT ButtonInfo { // Icon that should be displayed on the notification button. Optional. On some // platforms, a mask will be applied to the icon, to match the visual - // requirements of the notification. + // requirements of the notification. As with Android, MD notifications don't + // display this icon. gfx::Image icon; // The placeholder string that should be displayed in the input field for diff --git a/chromium/ui/message_center/public/mojo/notification.mojom b/chromium/ui/message_center/public/mojo/notification.mojom index eb7fba8b453..699d780971c 100644 --- a/chromium/ui/message_center/public/mojo/notification.mojom +++ b/chromium/ui/message_center/public/mojo/notification.mojom @@ -42,7 +42,8 @@ struct NotificationItem { // The fields and their meanings match message_center::ButtonInfo. struct ButtonInfo { mojo_base.mojom.String16 title; - gfx.mojom.ImageSkia? icon; + // |icon| intentionally omitted as it's not used on platforms that use mojo + // for notifications. mojo_base.mojom.String16? placeholder; }; diff --git a/chromium/ui/message_center/public/mojo/notification_struct_traits.cc b/chromium/ui/message_center/public/mojo/notification_struct_traits.cc index 3be58461182..78cca7ce2bd 100644 --- a/chromium/ui/message_center/public/mojo/notification_struct_traits.cc +++ b/chromium/ui/message_center/public/mojo/notification_struct_traits.cc @@ -36,19 +36,9 @@ bool NotificationItemStructTraits::Read( } // static -gfx::ImageSkia ButtonInfoStructTraits::icon( - const message_center::ButtonInfo& b) { - return b.icon.AsImageSkia(); -} - -// static bool ButtonInfoStructTraits::Read( message_center::mojom::ButtonInfoDataView data, ButtonInfo* out) { - gfx::ImageSkia icon; - if (!data.ReadIcon(&icon)) - return false; - out->icon = gfx::Image(icon); return data.ReadTitle(&out->title) && data.ReadPlaceholder(&out->placeholder); } diff --git a/chromium/ui/message_center/public/mojo/notification_struct_traits.h b/chromium/ui/message_center/public/mojo/notification_struct_traits.h index e2c68cbbab8..8789c8665e5 100644 --- a/chromium/ui/message_center/public/mojo/notification_struct_traits.h +++ b/chromium/ui/message_center/public/mojo/notification_struct_traits.h @@ -147,7 +147,6 @@ struct StructTraits<message_center::mojom::ButtonInfoDataView, static const base::string16& title(const message_center::ButtonInfo& b) { return b.title; } - static gfx::ImageSkia icon(const message_center::ButtonInfo& b); static const base::Optional<base::string16>& placeholder( const message_center::ButtonInfo& b) { return b.placeholder; diff --git a/chromium/ui/message_center/vector_icons/notification_snooze_button.icon b/chromium/ui/message_center/vector_icons/notification_snooze_button.icon index a62c3b42348..da0b7511282 100644 --- a/chromium/ui/message_center/vector_icons/notification_snooze_button.icon +++ b/chromium/ui/message_center/vector_icons/notification_snooze_button.icon @@ -5,9 +5,9 @@ // Converted from the svg files attached in http://crbug.com/840497. CANVAS_DIMENSIONS, 24, -MOVE_TO, 11.99f, 2, -ARC_TO, 10, 10, 0, 1, 0, 12, 21.99f, -ARC_TO, 10, 10, 0, 0, 0, 11.99f, 2, +MOVE_TO, 12, 2, +ARC_TO, 10, 10, 0, 1, 0, 12, 22, +ARC_TO, 10, 10, 0, 0, 0, 12, 2, CLOSE, MOVE_TO, 12, 20, R_ARC_TO, 8, 8, 0, 1, 1, 0, -16, diff --git a/chromium/ui/message_center/views/message_view.cc b/chromium/ui/message_center/views/message_view.cc index 86772103554..06de0192de7 100644 --- a/chromium/ui/message_center/views/message_view.cc +++ b/chromium/ui/message_center/views/message_view.cc @@ -130,21 +130,6 @@ void MessageView::CloseSwipeControl() { slide_out_controller_.CloseSwipeControl(); } -bool MessageView::IsCloseButtonFocused() const { - auto* control_buttons_view = GetControlButtonsView(); - return control_buttons_view ? control_buttons_view->IsCloseButtonFocused() - : false; -} - -void MessageView::RequestFocusOnCloseButton() { - auto* control_buttons_view = GetControlButtonsView(); - if (!control_buttons_view) - return; - - control_buttons_view->RequestFocusOnCloseButton(); - UpdateControlButtonsVisibility(); -} - void MessageView::SetExpanded(bool expanded) { // Not implemented by default. } @@ -383,6 +368,7 @@ float MessageView::GetSlideAmount() const { void MessageView::SetSettingMode(bool setting_mode) { setting_mode_ = setting_mode; slide_out_controller_.set_slide_mode(CalculateSlideMode()); + UpdateControlButtonsVisibility(); } void MessageView::DisableSlideForcibly(bool disable) { @@ -407,6 +393,26 @@ void MessageView::OnSnoozeButtonPressed(const ui::Event& event) { // No default implementation for snooze. } +bool MessageView::ShouldShowControlButtons() const { +#if defined(OS_CHROMEOS) + // Users on ChromeOS are used to the Settings and Close buttons not being + // visible at all times, but users on other platforms expect them to be + // visible. + auto* control_buttons_view = GetControlButtonsView(); + return control_buttons_view && + (control_buttons_view->IsAnyButtonFocused() || + (GetMode() != Mode::SETTING && IsMouseHovered())); +#else + return true; +#endif +} + +void MessageView::UpdateControlButtonsVisibility() { + auto* control_buttons_view = GetControlButtonsView(); + if (control_buttons_view) + control_buttons_view->ShowButtons(ShouldShowControlButtons()); +} + void MessageView::SetDrawBackgroundAsActive(bool active) { background()->SetNativeControlColor(active ? kHoveredButtonBackgroundColor : kNotificationBackgroundColor); diff --git a/chromium/ui/message_center/views/message_view.h b/chromium/ui/message_center/views/message_view.h index a0ea2aef23d..8b59c163bab 100644 --- a/chromium/ui/message_center/views/message_view.h +++ b/chromium/ui/message_center/views/message_view.h @@ -83,9 +83,6 @@ class MESSAGE_CENTER_EXPORT MessageView : public views::InkDropHostView, // Creates a shadow around the notification and changes slide-out behavior. void SetIsNested(); - bool IsCloseButtonFocused() const; - void RequestFocusOnCloseButton(); - virtual NotificationControlButtonsView* GetControlButtonsView() const = 0; virtual void SetExpanded(bool expanded); @@ -159,7 +156,7 @@ class MESSAGE_CENTER_EXPORT MessageView : public views::InkDropHostView, std::string notification_id() const { return notification_id_; } protected: - virtual void UpdateControlButtonsVisibility() = 0; + virtual void UpdateControlButtonsVisibility(); // Changes the background color and schedules a paint. virtual void SetDrawBackgroundAsActive(bool active); @@ -174,6 +171,9 @@ class MESSAGE_CENTER_EXPORT MessageView : public views::InkDropHostView, // Returns the ideal slide mode by calculating the current status. SlideOutController::SlideMode CalculateSlideMode() const; + // Returns if the control buttons should be shown. + bool ShouldShowControlButtons() const; + std::string notification_id_; views::ScrollView* scroller_ = nullptr; diff --git a/chromium/ui/message_center/views/message_view_factory.cc b/chromium/ui/message_center/views/message_view_factory.cc index 0ce0d313328..8db23c841cc 100644 --- a/chromium/ui/message_center/views/message_view_factory.cc +++ b/chromium/ui/message_center/views/message_view_factory.cc @@ -11,9 +11,12 @@ #include "base/lazy_instance.h" #include "ui/message_center/public/cpp/features.h" #include "ui/message_center/public/cpp/notification_types.h" -#include "ui/message_center/views/notification_view.h" #include "ui/message_center/views/notification_view_md.h" +#if !defined(OS_CHROMEOS) +#include "ui/message_center/views/notification_view.h" +#endif + namespace message_center { namespace { @@ -43,11 +46,7 @@ MessageView* MessageViewFactory::Create(const Notification& notification) { case NOTIFICATION_TYPE_MULTIPLE: case NOTIFICATION_TYPE_SIMPLE: case NOTIFICATION_TYPE_PROGRESS: - // All above roads lead to the generic NotificationView. - if (base::FeatureList::IsEnabled(message_center::kNewStyleNotifications)) - notification_view = new NotificationViewMD(notification); - else - notification_view = new NotificationView(notification); + // Rely on default construction after the switch. break; case NOTIFICATION_TYPE_CUSTOM: notification_view = GetCustomNotificationView(notification).release(); @@ -61,8 +60,21 @@ MessageView* MessageViewFactory::Create(const Notification& notification) { LOG(WARNING) << "Unable to fulfill request for unrecognized or" << "unsupported notification type " << notification.type() << ". Falling back to simple notification type."; + break; + } + + if (!notification_view) { +#if defined(OS_CHROMEOS) + notification_view = new NotificationViewMD(notification); +#else + // All above roads lead to the generic NotificationView. + if (base::FeatureList::IsEnabled(message_center::kNewStyleNotifications)) + notification_view = new NotificationViewMD(notification); + else notification_view = new NotificationView(notification); +#endif } + return notification_view; } diff --git a/chromium/ui/message_center/views/notification_control_buttons_view.cc b/chromium/ui/message_center/views/notification_control_buttons_view.cc index 4619a488ed7..09dff69aa2e 100644 --- a/chromium/ui/message_center/views/notification_control_buttons_view.cc +++ b/chromium/ui/message_center/views/notification_control_buttons_view.cc @@ -112,25 +112,18 @@ void NotificationControlButtonsView::ShowSnoozeButton(bool show) { } } -void NotificationControlButtonsView::SetVisible(bool visible) { +void NotificationControlButtonsView::ShowButtons(bool show) { DCHECK(layer()); // Manipulate the opacity instead of changing the visibility to keep the tab // order even when the view is invisible. - layer()->SetOpacity(visible ? 1. : 0.); - set_can_process_events_within_subtree(visible); + layer()->SetOpacity(show ? 1. : 0.); + set_can_process_events_within_subtree(show); } -void NotificationControlButtonsView::RequestFocusOnCloseButton() { - if (close_button_) - close_button_->RequestFocus(); -} - -bool NotificationControlButtonsView::IsCloseButtonFocused() const { - return close_button_ && close_button_->HasFocus(); -} - -bool NotificationControlButtonsView::IsSettingsButtonFocused() const { - return settings_button_ && settings_button_->HasFocus(); +bool NotificationControlButtonsView::IsAnyButtonFocused() const { + return (close_button_ && close_button_->HasFocus()) || + (settings_button_ && settings_button_->HasFocus()) || + (snooze_button_ && snooze_button_->HasFocus()); } views::Button* NotificationControlButtonsView::close_button() const { diff --git a/chromium/ui/message_center/views/notification_control_buttons_view.h b/chromium/ui/message_center/views/notification_control_buttons_view.h index b8b958baeb2..49717d2a9b5 100644 --- a/chromium/ui/message_center/views/notification_control_buttons_view.h +++ b/chromium/ui/message_center/views/notification_control_buttons_view.h @@ -42,16 +42,12 @@ class MESSAGE_CENTER_EXPORT NotificationControlButtonsView // Change the visibility of the settings button. True to show, false to hide. // Default: hidden. void ShowSnoozeButton(bool show); + // Change the visibility of all buttons. True to show, false to hide. + void ShowButtons(bool show); - // Request the focus on the close button. - void RequestFocusOnCloseButton(); - - // Return the focus status of the close button. True if the focus is on the - // close button, false otherwise. - bool IsCloseButtonFocused() const; - // Return the focus status of the settings button. True if the focus is on the - // close button, false otherwise. - bool IsSettingsButtonFocused() const; + // Return the focus status of any button. True if the focus is on any button, + // false otherwise. + bool IsAnyButtonFocused() const; // Methods for retrieving the control buttons directly. views::Button* close_button() const; @@ -60,7 +56,6 @@ class MESSAGE_CENTER_EXPORT NotificationControlButtonsView // views::View const char* GetClassName() const override; - void SetVisible(bool visible) override; // views::ButtonListener void ButtonPressed(views::Button* sender, const ui::Event& event) override; diff --git a/chromium/ui/message_center/views/notification_header_view.cc b/chromium/ui/message_center/views/notification_header_view.cc index 947da04c92c..5bae6eb98b4 100644 --- a/chromium/ui/message_center/views/notification_header_view.cc +++ b/chromium/ui/message_center/views/notification_header_view.cc @@ -25,6 +25,8 @@ #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/layout/flex_layout.h" +#include "ui/views/layout/flex_layout_types.h" #include "ui/views/painter.h" namespace message_center { @@ -32,7 +34,9 @@ namespace message_center { namespace { constexpr int kHeaderHeight = 32; -constexpr int kHeaderHorizontalSpacing = 2; + +// The padding between controls in the header. +constexpr gfx::Insets kHeaderSpacing(0, 2, 0, 2); // The padding outer the header and the control buttons. constexpr gfx::Insets kHeaderOuterPadding(2, 2, 0, 2); @@ -42,16 +46,11 @@ constexpr gfx::Insets kHeaderOuterPadding(2, 2, 0, 2); // Buttom: 6px from the mock. constexpr gfx::Insets kTextViewPaddingDefault(9, 0, 6, 0); -// Paddings of the entire header. -// Left: 14px = 16px (from the mock) - 2px (outer padding). -// Right: 2px = minimum padding between the control buttons and the header. -constexpr gfx::Insets kHeaderPadding(0, 14, 0, 2); - // Paddings of the app icon (small image). // Top: 8px = 10px (from the mock) - 2px (outer padding). // Bottom: 4px from the mock. // Right: 4px = 6px (from the mock) - kHeaderHorizontalSpacing. -constexpr gfx::Insets kAppIconPadding(8, 0, 4, 4); +constexpr gfx::Insets kAppIconPadding(8, 14, 4, 4); // Size of the expand icon. 8px = 32px - 15px - 9px (values from the mock). constexpr int kExpandIconSize = 8; @@ -187,19 +186,22 @@ NotificationHeaderView::NotificationHeaderView( : views::Button(listener) { const int kInnerHeaderHeight = kHeaderHeight - kHeaderOuterPadding.height(); - auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kHeaderOuterPadding, - kHeaderHorizontalSpacing)); - layout->set_cross_axis_alignment( - views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); + const views::FlexSpecification kAppNameFlex = + views::FlexSpecification::ForSizeRule( + views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kPreferred) + .WithOrder(1); - views::View* app_info_container = new views::View(); - auto app_info_layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kHeaderPadding, kHeaderHorizontalSpacing); - app_info_layout->set_cross_axis_alignment( - views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); - app_info_container->SetLayoutManager(std::move(app_info_layout)); - AddChildView(app_info_container); + const views::FlexSpecification kSpacerFlex = + views::FlexSpecification::ForSizeRule( + views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kUnbounded) + .WithOrder(2); + + auto* layout = SetLayoutManager(std::make_unique<views::FlexLayout>()); + layout->SetDefaultChildMargins(kHeaderSpacing); + layout->SetInteriorMargin(kHeaderOuterPadding); + layout->SetCollapseMargins(true); // App icon view app_icon_view_ = new views::ImageView(); @@ -208,7 +210,7 @@ NotificationHeaderView::NotificationHeaderView( app_icon_view_->SetVerticalAlignment(views::ImageView::LEADING); app_icon_view_->SetHorizontalAlignment(views::ImageView::LEADING); DCHECK_EQ(kInnerHeaderHeight, app_icon_view_->GetPreferredSize().height()); - app_info_container->AddChildView(app_icon_view_); + AddChildView(app_icon_view_); // Font list for text views. gfx::FontList font_list = GetHeaderTextFontList(); @@ -217,13 +219,16 @@ NotificationHeaderView::NotificationHeaderView( // App name view app_name_view_ = new views::Label(base::string16()); + // Explicitly disable multiline to support proper text elision for URLs. + app_name_view_->SetMultiLine(false); app_name_view_->SetFontList(font_list); app_name_view_->SetLineHeight(font_list_height); app_name_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); app_name_view_->SetEnabledColor(accent_color_); app_name_view_->SetBorder(views::CreateEmptyBorder(text_view_padding)); DCHECK_EQ(kInnerHeaderHeight, app_name_view_->GetPreferredSize().height()); - app_info_container->AddChildView(app_name_view_); + AddChildView(app_name_view_); + layout->SetFlexForView(app_name_view_, kAppNameFlex); // Summary text divider summary_text_divider_ = @@ -235,7 +240,7 @@ NotificationHeaderView::NotificationHeaderView( summary_text_divider_->SetVisible(false); DCHECK_EQ(kInnerHeaderHeight, summary_text_divider_->GetPreferredSize().height()); - app_info_container->AddChildView(summary_text_divider_); + AddChildView(summary_text_divider_); // Summary text view summary_text_view_ = new views::Label(base::string16()); @@ -246,7 +251,7 @@ NotificationHeaderView::NotificationHeaderView( summary_text_view_->SetVisible(false); DCHECK_EQ(kInnerHeaderHeight, summary_text_view_->GetPreferredSize().height()); - app_info_container->AddChildView(summary_text_view_); + AddChildView(summary_text_view_); // Timestamp divider timestamp_divider_ = @@ -258,7 +263,7 @@ NotificationHeaderView::NotificationHeaderView( timestamp_divider_->SetVisible(false); DCHECK_EQ(kInnerHeaderHeight, timestamp_divider_->GetPreferredSize().height()); - app_info_container->AddChildView(timestamp_divider_); + AddChildView(timestamp_divider_); // Timestamp view timestamp_view_ = new views::Label(base::string16()); @@ -268,7 +273,7 @@ NotificationHeaderView::NotificationHeaderView( timestamp_view_->SetBorder(views::CreateEmptyBorder(text_view_padding)); timestamp_view_->SetVisible(false); DCHECK_EQ(kInnerHeaderHeight, timestamp_view_->GetPreferredSize().height()); - app_info_container->AddChildView(timestamp_view_); + AddChildView(timestamp_view_); // Expand button view expand_button_ = new ExpandButton(); @@ -278,13 +283,13 @@ NotificationHeaderView::NotificationHeaderView( expand_button_->SetHorizontalAlignment(views::ImageView::LEADING); expand_button_->SetImageSize(gfx::Size(kExpandIconSize, kExpandIconSize)); DCHECK_EQ(kInnerHeaderHeight, expand_button_->GetPreferredSize().height()); - app_info_container->AddChildView(expand_button_); + AddChildView(expand_button_); // Spacer between left-aligned views and right-aligned views views::View* spacer = new views::View; spacer->SetPreferredSize(gfx::Size(1, kInnerHeaderHeight)); AddChildView(spacer); - layout->SetFlexForView(spacer, 1); + layout->SetFlexForView(spacer, kSpacerFlex); // Settings and close buttons view AddChildView(control_buttons_view); @@ -305,6 +310,11 @@ void NotificationHeaderView::SetAppName(const base::string16& name) { app_name_view_->SetText(name); } +void NotificationHeaderView::SetAppNameElideBehavior( + gfx::ElideBehavior elide_behavior) { + app_name_view_->SetElideBehavior(elide_behavior); +} + void NotificationHeaderView::SetProgress(int progress) { summary_text_view_->SetText(l10n_util::GetStringFUTF16Int( IDS_MESSAGE_CENTER_NOTIFICATION_PROGRESS_PERCENTAGE, progress)); @@ -397,6 +407,10 @@ std::unique_ptr<views::InkDrop> NotificationHeaderView::CreateInkDrop() { return std::make_unique<views::InkDropStub>(); } +const base::string16& NotificationHeaderView::app_name_for_testing() const { + return app_name_view_->text(); +} + void NotificationHeaderView::UpdateSummaryTextVisibility() { const bool visible = has_progress_ || has_overflow_indicator_; summary_text_divider_->SetVisible(visible); diff --git a/chromium/ui/message_center/views/notification_header_view.h b/chromium/ui/message_center/views/notification_header_view.h index 72f6caa7e51..edca12dc960 100644 --- a/chromium/ui/message_center/views/notification_header_view.h +++ b/chromium/ui/message_center/views/notification_header_view.h @@ -6,6 +6,7 @@ #define UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_HEADER_VIEW_H_ #include "base/macros.h" +#include "ui/gfx/text_constants.h" #include "ui/message_center/message_center_export.h" #include "ui/message_center/public/cpp/message_center_constants.h" #include "ui/views/controls/button/button.h" @@ -25,6 +26,7 @@ class MESSAGE_CENTER_EXPORT NotificationHeaderView : public views::Button { views::ButtonListener* listener); void SetAppIcon(const gfx::ImageSkia& img); void SetAppName(const base::string16& name); + void SetAppNameElideBehavior(gfx::ElideBehavior elide_behavior); void SetProgress(int progress); void SetOverflowIndicator(int count); void SetTimestamp(base::Time past); @@ -53,6 +55,8 @@ class MESSAGE_CENTER_EXPORT NotificationHeaderView : public views::Button { SkColor accent_color_for_testing() { return accent_color_; } + const base::string16& app_name_for_testing() const; + private: // Update visibility for both |summary_text_view_| and |timestamp_view_|. void UpdateSummaryTextVisibility(); diff --git a/chromium/ui/message_center/views/notification_view.cc b/chromium/ui/message_center/views/notification_view.cc index 1bea4a1494e..08f43237f00 100644 --- a/chromium/ui/message_center/views/notification_view.cc +++ b/chromium/ui/message_center/views/notification_view.cc @@ -112,11 +112,6 @@ void SetBorderRight(views::View* view, int right) { class NotificationItemView : public views::View { public: explicit NotificationItemView(const NotificationItem& item); - ~NotificationItemView() override; - - // Overridden from views::View: - void SetVisible(bool visible) override; - private: DISALLOW_COPY_AND_ASSIGN(NotificationItemView); }; @@ -144,14 +139,6 @@ NotificationItemView::NotificationItemView(const NotificationItem& item) { SchedulePaint(); } -NotificationItemView::~NotificationItemView() {} - -void NotificationItemView::SetVisible(bool visible) { - views::View::SetVisible(visible); - for (int i = 0; i < child_count(); ++i) - child_at(i)->SetVisible(visible); -} - } // namespace // NotificationView //////////////////////////////////////////////////////////// @@ -631,59 +618,21 @@ void NotificationView::UpdateControlButtonsVisibilityWithNotification( UpdateControlButtonsVisibility(); } -void NotificationView::UpdateControlButtonsVisibility() { -#if defined(OS_CHROMEOS) - // On Chrome OS, the settings button and the close button are shown when: - // (1) the mouse is hovering on the notification. - // (2) the focus is on the control buttons. - const bool target_visibility = - IsMouseHovered() || control_buttons_view_->IsCloseButtonFocused() || - control_buttons_view_->IsSettingsButtonFocused(); -#else - // On non Chrome OS, the settings button and the close button are always - // shown. - const bool target_visibility = true; -#endif - - control_buttons_view_->SetVisible(target_visibility); -} - NotificationControlButtonsView* NotificationView::GetControlButtonsView() const { return control_buttons_view_; } int NotificationView::GetMessageLineLimit(int title_lines, int width) const { - // Image notifications require that the image must be kept flush against - // their icons, but we can allow more text if no image. int effective_title_lines = std::max(0, title_lines - 1); - int line_reduction_from_title = (image_view_ ? 1 : 2) * effective_title_lines; - if (!image_view_) { - // Title lines are counted as twice as big as message lines for the purpose - // of this calculation. - // The effect from the title reduction here should be: - // * 0 title lines: 5 max lines message. - // * 1 title line: 5 max lines message. - // * 2 title lines: 3 max lines message. - return std::max(0, kMessageExpandedLineLimit - line_reduction_from_title); - } - - int message_line_limit = kMessageCollapsedLineLimit; - - // Subtract any lines taken by the context message. - if (context_message_view_) { - message_line_limit -= context_message_view_->GetLinesForWidthAndLimit( - width, kContextMessageLineLimit); - } - + int line_reduction_from_title = 2 * effective_title_lines; + // Title lines are counted as twice as big as message lines for the purpose + // of this calculation. // The effect from the title reduction here should be: - // * 0 title lines: 2 max lines message + context message. - // * 1 title line: 2 max lines message + context message. - // * 2 title lines: 1 max lines message + context message. - message_line_limit = - std::max(0, message_line_limit - line_reduction_from_title); - - return message_line_limit; + // * 0 title lines: 5 max lines message. + // * 1 title line: 5 max lines message. + // * 2 title lines: 3 max lines message. + return std::max(0, kMessageExpandedLineLimit - line_reduction_from_title); } int NotificationView::GetMessageHeight(int width, int limit) const { diff --git a/chromium/ui/message_center/views/notification_view.h b/chromium/ui/message_center/views/notification_view.h index e58e29e7bc0..e2e5507aea1 100644 --- a/chromium/ui/message_center/views/notification_view.h +++ b/chromium/ui/message_center/views/notification_view.h @@ -48,7 +48,6 @@ class MESSAGE_CENTER_EXPORT NotificationView : public MessageView, // Overridden from MessageView: void UpdateWithNotification(const Notification& notification) override; void ButtonPressed(views::Button* sender, const ui::Event& event) override; - void UpdateControlButtonsVisibility() override; NotificationControlButtonsView* GetControlButtonsView() const override; private: diff --git a/chromium/ui/message_center/views/notification_view_md.cc b/chromium/ui/message_center/views/notification_view_md.cc index e6fcbfff3cf..9da43a65e37 100644 --- a/chromium/ui/message_center/views/notification_view_md.cc +++ b/chromium/ui/message_center/views/notification_view_md.cc @@ -17,10 +17,12 @@ #include "ui/events/gesture_detection/gesture_provider_config_helper.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_palette.h" +#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/skia_util.h" +#include "ui/gfx/text_constants.h" #include "ui/gfx/text_elider.h" #include "ui/message_center/message_center.h" #include "ui/message_center/public/cpp/message_center_constants.h" @@ -36,6 +38,7 @@ #include "ui/strings/grit/ui_strings.h" #include "ui/views/animation/flood_fill_ink_drop_ripple.h" #include "ui/views/animation/ink_drop_highlight.h" +#include "ui/views/animation/ink_drop_mask.h" #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/button/image_button.h" @@ -135,16 +138,6 @@ constexpr double kProgressNotificationMessageRatio = 0.7; // This key/property allows tagging the textfield with its index. DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(int, kTextfieldIndexKey, 0U); -// Users on ChromeOS are used to the Settings and Close buttons not being -// visible at all times, but users on other platforms expect them to be visible. -constexpr bool AlwaysShowControlButtons() { -#if defined(OS_CHROMEOS) - return false; -#else - return true; -#endif -} - // FontList for the texts except for the header. gfx::FontList GetTextFontList() { gfx::Font default_font; @@ -593,7 +586,7 @@ void NotificationViewMD::Layout() { // Use vertically larger clip path, so that actions row's top coners will // not be rounded. - gfx::Path path; + SkPath path; gfx::Rect bounds = actions_row_->GetLocalBounds(); bounds.set_y(bounds.y() - bounds.height()); bounds.set_height(bounds.height() * 2); @@ -614,6 +607,13 @@ void NotificationViewMD::Layout() { } } +void NotificationViewMD::OnBoundsChanged(const gfx::Rect& previous_bounds) { + if (ink_drop_layer_) + ink_drop_layer_->SetBounds(gfx::Rect(size())); + if (ink_drop_mask_) + ink_drop_mask_->layer()->SetBounds(gfx::Rect(size())); +} + void NotificationViewMD::OnFocus() { MessageView::OnFocus(); ScrollRectToVisible(GetLocalBounds()); @@ -766,6 +766,7 @@ void NotificationViewMD::CreateOrUpdateContextTitleView( ? kNotificationDefaultAccentColor : notification.accent_color()); header_row_->SetTimestamp(notification.timestamp()); + header_row_->SetAppNameElideBehavior(gfx::ELIDE_TAIL); base::string16 app_name = notification.display_source(); if (notification.origin_url().is_valid() && @@ -773,6 +774,7 @@ void NotificationViewMD::CreateOrUpdateContextTitleView( app_name = url_formatter::FormatUrlForSecurityDisplay( notification.origin_url(), url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS); + header_row_->SetAppNameElideBehavior(gfx::ELIDE_HEAD); } else if (app_name.empty() && notification.notifier_id().type == NotifierType::SYSTEM_COMPONENT) { app_name = MessageCenter::Get()->GetSystemNotificationAppName(); @@ -800,7 +802,7 @@ void NotificationViewMD::CreateOrUpdateTitleView( title_view_ = new views::Label(title); title_view_->SetFontList(font_list); - title_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + title_view_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); title_view_->SetEnabledColor(kRegularTextColorMD); left_content_->AddChildViewAt(title_view_, left_content_count_); } else { @@ -967,14 +969,17 @@ void NotificationViewMD::CreateOrUpdateIconView( void NotificationViewMD::CreateOrUpdateSmallIconView( const Notification& notification) { - if (!notification.vector_small_image().is_empty()) { - header_row_->SetAppIcon( - gfx::CreateVectorIcon(notification.vector_small_image(), - kSmallImageSizeMD, notification.accent_color())); - } else if (!notification.small_image().IsEmpty()) { - header_row_->SetAppIcon(notification.small_image().AsImageSkia()); - } else { + // TODO(knollr): figure out if this has a performance impact and + // cache images if so. (crbug.com/768748) + gfx::Image masked_small_icon = notification.GenerateMaskedSmallIcon( + kSmallImageSizeMD, notification.accent_color() == SK_ColorTRANSPARENT + ? message_center::kNotificationDefaultAccentColor + : notification.accent_color()); + + if (masked_small_icon.IsEmpty()) { header_row_->ClearAppIcon(); + } else { + header_row_->SetAppIcon(masked_small_icon.AsImageSkia()); } } @@ -1242,23 +1247,13 @@ void NotificationViewMD::ToggleInlineSettings(const ui::Event& event) { MessageCenter::Get()->DisableNotification(notification_id()); } -// TODO(yoshiki): Move this to the parent class (MessageView) and share the code -// among NotificationView and ArcNotificationView. -void NotificationViewMD::UpdateControlButtonsVisibility() { - const bool target_visibility = - (AlwaysShowControlButtons() || IsMouseHovered() || - control_buttons_view_->IsCloseButtonFocused() || - control_buttons_view_->IsSettingsButtonFocused()) && - (GetMode() != Mode::SETTING); - - control_buttons_view_->SetVisible(target_visibility); -} - void NotificationViewMD::UpdateCornerRadius(int top_radius, int bottom_radius) { MessageView::UpdateCornerRadius(top_radius, bottom_radius); action_buttons_row_->SetBackground(views::CreateBackgroundFromPainter( std::make_unique<NotificationBackgroundPainter>( 0, bottom_radius, kActionsRowBackgroundColor))); + top_radius_ = top_radius; + bottom_radius_ = bottom_radius; } NotificationControlButtonsView* NotificationViewMD::GetControlButtonsView() @@ -1326,6 +1321,7 @@ void NotificationViewMD::AddBackgroundAnimation(const ui::Event& event) { } void NotificationViewMD::RemoveBackgroundAnimation() { + SetInkDropMode(InkDropMode::OFF); AnimateInkDrop(views::InkDropState::HIDDEN, nullptr); } @@ -1340,7 +1336,8 @@ void NotificationViewMD::AddInkDropLayer(ui::Layer* ink_drop_layer) { settings_done_button_->SetPaintToLayer(); settings_done_button_->layer()->SetFillsBoundsOpaquely(false); ink_drop_container_->AddInkDropLayer(ink_drop_layer); - InstallInkDropMask(ink_drop_layer); + ink_drop_layer_ = ink_drop_layer; + InstallNotificationInkDropMask(); } void NotificationViewMD::RemoveInkDropLayer(ui::Layer* ink_drop_layer) { @@ -1348,18 +1345,38 @@ void NotificationViewMD::RemoveInkDropLayer(ui::Layer* ink_drop_layer) { block_all_button_->DestroyLayer(); dont_block_button_->DestroyLayer(); settings_done_button_->DestroyLayer(); - ResetInkDropMask(); + ink_drop_mask_.reset(); ink_drop_container_->RemoveInkDropLayer(ink_drop_layer); GetInkDrop()->RemoveObserver(this); + ink_drop_layer_ = nullptr; } std::unique_ptr<views::InkDropRipple> NotificationViewMD::CreateInkDropRipple() const { return std::make_unique<views::FloodFillInkDropRipple>( - ink_drop_container_->size(), GetInkDropCenterBasedOnLastEvent(), + GetPreferredSize(), GetInkDropCenterBasedOnLastEvent(), GetInkDropBaseColor(), ink_drop_visible_opacity()); } +void NotificationViewMD::InstallNotificationInkDropMask() { + SkPath path; + SkScalar radii[8] = {top_radius_, top_radius_, top_radius_, + top_radius_, bottom_radius_, bottom_radius_, + bottom_radius_, bottom_radius_}; + gfx::Rect rect(GetPreferredSize()); + path.addRoundRect(gfx::RectToSkRect(rect), radii); + ink_drop_mask_ = std::make_unique<views::PathInkDropMask>(size(), path); + ink_drop_layer_->SetMaskLayer(ink_drop_mask_->layer()); +} + +std::unique_ptr<views::InkDropMask> NotificationViewMD::CreateInkDropMask() + const { + // We don't use this as we need access to the |ink_drop_mask_|. + // See crbug.com/915222. + NOTREACHED(); + return nullptr; +} + SkColor NotificationViewMD::GetInkDropBaseColor() const { // Background of inline settings area. return SkColorSetRGB(0xEE, 0xEE, 0xEE); diff --git a/chromium/ui/message_center/views/notification_view_md.h b/chromium/ui/message_center/views/notification_view_md.h index a954fff6d6f..9ec098ae9a1 100644 --- a/chromium/ui/message_center/views/notification_view_md.h +++ b/chromium/ui/message_center/views/notification_view_md.h @@ -173,6 +173,7 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD // Overridden from views::View: void Layout() override; + void OnBoundsChanged(const gfx::Rect& previous_bounds) override; void OnFocus() override; bool OnMousePressed(const ui::MouseEvent& event) override; bool OnMouseDragged(const ui::MouseEvent& event) override; @@ -184,12 +185,12 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD void AddInkDropLayer(ui::Layer* ink_drop_layer) override; void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override; std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override; + std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; SkColor GetInkDropBaseColor() const override; // Overridden from MessageView: void UpdateWithNotification(const Notification& notification) override; void ButtonPressed(views::Button* sender, const ui::Event& event) override; - void UpdateControlButtonsVisibility() override; void UpdateCornerRadius(int top_radius, int bottom_radius) override; NotificationControlButtonsView* GetControlButtonsView() const override; bool IsExpanded() const override; @@ -252,6 +253,9 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD void UpdateViewForExpandedState(bool expanded); void ToggleInlineSettings(const ui::Event& event); + // Initializes |ink_drop_mask_| and sets the mask on |ink_drop_layer_|. + void InstallNotificationInkDropMask(); + views::InkDropContainerView* const ink_drop_container_; // View containing close and settings buttons @@ -273,6 +277,15 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD // Describes whether the view should display a hand pointer or not. bool clickable_; + // Corner radii for the InkDropMask. + int top_radius_ = 0; + int bottom_radius_ = 0; + + // The InkDrop layer and InkDropMask used to update their bounds on + // OnBoundsChanged(). See crbug.com/915222. + ui::Layer* ink_drop_layer_ = nullptr; + std::unique_ptr<views::InkDropMask> ink_drop_mask_; + // Container views directly attached to this view. NotificationHeaderView* header_row_ = nullptr; views::View* content_row_ = nullptr; diff --git a/chromium/ui/message_center/views/notification_view_md_unittest.cc b/chromium/ui/message_center/views/notification_view_md_unittest.cc index bd23045b068..bf98dcaf4db 100644 --- a/chromium/ui/message_center/views/notification_view_md_unittest.cc +++ b/chromium/ui/message_center/views/notification_view_md_unittest.cc @@ -256,7 +256,6 @@ const SkBitmap NotificationViewMDTest::CreateBitmap(int width, std::vector<ButtonInfo> NotificationViewMDTest::CreateButtons(int number) { ButtonInfo info(base::ASCIIToUTF16("Test button.")); - info.icon = CreateTestImage(4, 4); return std::vector<ButtonInfo>(number, info); } @@ -1040,19 +1039,21 @@ TEST_F(NotificationViewMDTest, InlineSettings) { generator.ClickLeftButton(); EXPECT_TRUE(notification_view()->settings_row_->visible()); - // By clicking settings button again, it will toggle. +#if !defined(OS_CHROMEOS) + // By clicking settings button again, it will toggle. Skip this on ChromeOS as + // the control_buttons_view gets hidden when the inline settings are shown. generator.ClickLeftButton(); EXPECT_FALSE(notification_view()->settings_row_->visible()); // Show inline settings again. generator.ClickLeftButton(); EXPECT_TRUE(notification_view()->settings_row_->visible()); +#endif // Construct a mouse click event 1 pixel inside the done button. gfx::Point done_cursor_location(1, 1); - views::View::ConvertPointToTarget( - notification_view()->control_buttons_view_->settings_button(), - notification_view(), &done_cursor_location); + views::View::ConvertPointToTarget(notification_view()->settings_done_button_, + notification_view(), &done_cursor_location); generator.MoveMouseTo(done_cursor_location); generator.ClickLeftButton(); diff --git a/chromium/ui/message_center/views/notification_view_unittest.cc b/chromium/ui/message_center/views/notification_view_unittest.cc index eb7f688f821..c464eff269f 100644 --- a/chromium/ui/message_center/views/notification_view_unittest.cc +++ b/chromium/ui/message_center/views/notification_view_unittest.cc @@ -391,18 +391,18 @@ TEST_F(NotificationViewTest, TestLineLimits) { notification()->set_image(CreateTestImage(2, 2)); notification_view()->UpdateWithNotification(*notification()); - EXPECT_EQ(2, notification_view()->GetMessageLineLimit(0, 360)); - EXPECT_EQ(2, notification_view()->GetMessageLineLimit(1, 360)); - EXPECT_EQ(1, notification_view()->GetMessageLineLimit(2, 360)); + EXPECT_EQ(5, notification_view()->GetMessageLineLimit(0, 360)); + EXPECT_EQ(5, notification_view()->GetMessageLineLimit(1, 360)); + EXPECT_EQ(3, notification_view()->GetMessageLineLimit(2, 360)); notification()->set_context_message(base::ASCIIToUTF16("foo")); notification_view()->UpdateWithNotification(*notification()); EXPECT_TRUE(notification_view()->context_message_view_ != NULL); - EXPECT_EQ(1, notification_view()->GetMessageLineLimit(0, 360)); - EXPECT_EQ(1, notification_view()->GetMessageLineLimit(1, 360)); - EXPECT_EQ(0, notification_view()->GetMessageLineLimit(2, 360)); + EXPECT_EQ(5, notification_view()->GetMessageLineLimit(0, 360)); + EXPECT_EQ(5, notification_view()->GetMessageLineLimit(1, 360)); + EXPECT_EQ(3, notification_view()->GetMessageLineLimit(2, 360)); } TEST_F(NotificationViewTest, TestIconSizing) { |