Commit ed1035e0 authored by Tetsui Ohkubo's avatar Tetsui Ohkubo Committed by Commit Bot

Unified: Implement clear all notifications button.

In UnifiedSystemTray, notification list should have Clear All button at
the bottom of the list.

UX spec: http://shortn/_SbJoaT9xpn
Screenshot: http://screen/xdFEFjJTs5x

TEST=manual
BUG=851830

Change-Id: Ia08f4c773d6b155c53e3b189cc9cca743e12150d
Reviewed-on: https://chromium-review.googlesource.com/1096808Reviewed-by: default avatarYoshiki Iguchi <yoshiki@chromium.org>
Commit-Queue: Tetsui Ohkubo <tetsui@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567598}
parent b5860113
...@@ -19,14 +19,9 @@ ...@@ -19,14 +19,9 @@
namespace ash { namespace ash {
SignOutButton::SignOutButton(views::ButtonListener* listener) RoundedLabelButton::RoundedLabelButton(views::ButtonListener* listener,
: views::LabelButton(listener, const base::string16& text)
user::GetLocalizedSignOutStringForStatus( : views::LabelButton(listener, text) {
Shell::Get()->session_controller()->login_status(),
false /* multiline */)) {
SetVisible(Shell::Get()->session_controller()->login_status() !=
LoginStatus::NOT_LOGGED_IN);
SetEnabledTextColors(kUnifiedMenuTextColor); SetEnabledTextColors(kUnifiedMenuTextColor);
SetHorizontalAlignment(gfx::ALIGN_CENTER); SetHorizontalAlignment(gfx::ALIGN_CENTER);
SetBorder(views::CreateEmptyBorder(gfx::Insets())); SetBorder(views::CreateEmptyBorder(gfx::Insets()));
...@@ -34,18 +29,18 @@ SignOutButton::SignOutButton(views::ButtonListener* listener) ...@@ -34,18 +29,18 @@ SignOutButton::SignOutButton(views::ButtonListener* listener)
TrayPopupUtils::ConfigureTrayPopupButton(this); TrayPopupUtils::ConfigureTrayPopupButton(this);
} }
SignOutButton::~SignOutButton() = default; RoundedLabelButton::~RoundedLabelButton() = default;
gfx::Size SignOutButton::CalculatePreferredSize() const { gfx::Size RoundedLabelButton::CalculatePreferredSize() const {
return gfx::Size(label()->GetPreferredSize().width() + kTrayItemSize, return gfx::Size(label()->GetPreferredSize().width() + kTrayItemSize,
kTrayItemSize); kTrayItemSize);
} }
int SignOutButton::GetHeightForWidth(int width) const { int RoundedLabelButton::GetHeightForWidth(int width) const {
return kTrayItemSize; return kTrayItemSize;
} }
void SignOutButton::PaintButtonContents(gfx::Canvas* canvas) { void RoundedLabelButton::PaintButtonContents(gfx::Canvas* canvas) {
gfx::Rect rect(GetContentsBounds()); gfx::Rect rect(GetContentsBounds());
cc::PaintFlags flags; cc::PaintFlags flags;
flags.setAntiAlias(true); flags.setAntiAlias(true);
...@@ -56,26 +51,38 @@ void SignOutButton::PaintButtonContents(gfx::Canvas* canvas) { ...@@ -56,26 +51,38 @@ void SignOutButton::PaintButtonContents(gfx::Canvas* canvas) {
views::LabelButton::PaintButtonContents(canvas); views::LabelButton::PaintButtonContents(canvas);
} }
std::unique_ptr<views::InkDrop> SignOutButton::CreateInkDrop() { std::unique_ptr<views::InkDrop> RoundedLabelButton::CreateInkDrop() {
return TrayPopupUtils::CreateInkDrop(this); return TrayPopupUtils::CreateInkDrop(this);
} }
std::unique_ptr<views::InkDropRipple> SignOutButton::CreateInkDropRipple() std::unique_ptr<views::InkDropRipple> RoundedLabelButton::CreateInkDropRipple()
const { const {
return TrayPopupUtils::CreateInkDropRipple( return TrayPopupUtils::CreateInkDropRipple(
TrayPopupInkDropStyle::FILL_BOUNDS, this, TrayPopupInkDropStyle::FILL_BOUNDS, this,
GetInkDropCenterBasedOnLastEvent(), kUnifiedMenuIconColor); GetInkDropCenterBasedOnLastEvent(), kUnifiedMenuIconColor);
} }
std::unique_ptr<views::InkDropHighlight> SignOutButton::CreateInkDropHighlight() std::unique_ptr<views::InkDropHighlight>
const { RoundedLabelButton::CreateInkDropHighlight() const {
return TrayPopupUtils::CreateInkDropHighlight( return TrayPopupUtils::CreateInkDropHighlight(
TrayPopupInkDropStyle::FILL_BOUNDS, this, kUnifiedMenuIconColor); TrayPopupInkDropStyle::FILL_BOUNDS, this, kUnifiedMenuIconColor);
} }
std::unique_ptr<views::InkDropMask> SignOutButton::CreateInkDropMask() const { std::unique_ptr<views::InkDropMask> RoundedLabelButton::CreateInkDropMask()
const {
return std::make_unique<views::RoundRectInkDropMask>(size(), gfx::Insets(), return std::make_unique<views::RoundRectInkDropMask>(size(), gfx::Insets(),
kTrayItemSize / 2); kTrayItemSize / 2);
} }
SignOutButton::SignOutButton(views::ButtonListener* listener)
: RoundedLabelButton(listener,
user::GetLocalizedSignOutStringForStatus(
Shell::Get()->session_controller()->login_status(),
false /* multiline */)) {
SetVisible(Shell::Get()->session_controller()->login_status() !=
LoginStatus::NOT_LOGGED_IN);
}
SignOutButton::~SignOutButton() = default;
} // namespace ash } // namespace ash
...@@ -9,13 +9,12 @@ ...@@ -9,13 +9,12 @@
namespace ash { namespace ash {
// Sign out button shown in TopShortcutView with TopShortcutButtons. // LabelButton that has rounded shape with Material Design ink drop.
// Shows the label like "Sign out", "Exit guest", etc. depending on the session class RoundedLabelButton : public views::LabelButton {
// status. Not visible when not signed in.
class SignOutButton : public views::LabelButton {
public: public:
SignOutButton(views::ButtonListener* listener); RoundedLabelButton(views::ButtonListener* listener,
~SignOutButton() override; const base::string16& text);
~RoundedLabelButton() override;
// views::LabelButton: // views::LabelButton:
gfx::Size CalculatePreferredSize() const override; gfx::Size CalculatePreferredSize() const override;
...@@ -27,6 +26,18 @@ class SignOutButton : public views::LabelButton { ...@@ -27,6 +26,18 @@ class SignOutButton : public views::LabelButton {
const override; const override;
std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override;
private:
DISALLOW_COPY_AND_ASSIGN(RoundedLabelButton);
};
// Sign out button shown in TopShortcutView with TopShortcutButtons.
// Shows the label like "Sign out", "Exit guest", etc. depending on the session
// status. Not visible when not signed in.
class SignOutButton : public RoundedLabelButton {
public:
explicit SignOutButton(views::ButtonListener* listener);
~SignOutButton() override;
private: private:
DISALLOW_COPY_AND_ASSIGN(SignOutButton); DISALLOW_COPY_AND_ASSIGN(SignOutButton);
}; };
......
...@@ -4,13 +4,18 @@ ...@@ -4,13 +4,18 @@
#include "ash/system/unified/unified_message_center_view.h" #include "ash/system/unified/unified_message_center_view.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_constants.h"
#include "ash/system/unified/sign_out_button.h"
#include "ash/system/unified/unified_system_tray_controller.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/message_center.h" #include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_types.h" #include "ui/message_center/message_center_types.h"
#include "ui/message_center/views/message_view.h" #include "ui/message_center/views/message_view.h"
#include "ui/message_center/views/message_view_factory.h" #include "ui/message_center/views/message_view_factory.h"
#include "ui/views/controls/scroll_view.h" #include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/scrollbar/overlay_scroll_bar.h" #include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
#include "ui/views/layout/box_layout.h"
using message_center::MessageCenter; using message_center::MessageCenter;
using message_center::MessageView; using message_center::MessageView;
...@@ -29,8 +34,10 @@ const int kMaxVisibleNotifications = 100; ...@@ -29,8 +34,10 @@ const int kMaxVisibleNotifications = 100;
// /////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////
UnifiedMessageCenterView::UnifiedMessageCenterView( UnifiedMessageCenterView::UnifiedMessageCenterView(
UnifiedSystemTrayController* tray_controller,
MessageCenter* message_center) MessageCenter* message_center)
: message_center_(message_center), : tray_controller_(tray_controller),
message_center_(message_center),
scroller_(new views::ScrollView()), scroller_(new views::ScrollView()),
message_list_view_(new MessageListView()) { message_list_view_(new MessageListView()) {
SetPaintToLayer(); SetPaintToLayer();
...@@ -48,11 +55,32 @@ UnifiedMessageCenterView::UnifiedMessageCenterView( ...@@ -48,11 +55,32 @@ UnifiedMessageCenterView::UnifiedMessageCenterView(
scroller_->set_draw_overflow_indicator(false); scroller_->set_draw_overflow_indicator(false);
AddChildView(scroller_); AddChildView(scroller_);
message_list_view_->SetBorder(
views::CreateEmptyBorder(0, 0, kUnifiedNotificationCenterSpacing, 0));
message_list_view_->set_use_fixed_height(false); message_list_view_->set_use_fixed_height(false);
message_list_view_->set_scroller(scroller_); message_list_view_->set_scroller(scroller_);
scroller_->SetContents(message_list_view_); message_list_view_->AddObserver(this);
views::View* scroller_contents = new views::View;
auto* contents_layout = scroller_contents->SetLayoutManager(
std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical));
contents_layout->set_cross_axis_alignment(
views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
scroller_contents->AddChildView(message_list_view_);
views::View* button_container = new views::View;
auto* button_layout =
button_container->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::kHorizontal,
gfx::Insets(kUnifiedNotificationCenterSpacing), 0));
button_layout->set_main_axis_alignment(
views::BoxLayout::MAIN_AXIS_ALIGNMENT_END);
auto* clear_all_button = new RoundedLabelButton(
this, l10n_util::GetStringUTF16(
IDS_ASH_MESSAGE_CENTER_CLEAR_ALL_BUTTON_TOOLTIP));
button_container->AddChildView(clear_all_button);
scroller_contents->AddChildView(button_container);
scroller_->SetContents(scroller_contents);
SetNotifications(message_center_->GetVisibleNotifications()); SetNotifications(message_center_->GetVisibleNotifications());
} }
...@@ -66,6 +94,11 @@ void UnifiedMessageCenterView::SetMaxHeight(int max_height) { ...@@ -66,6 +94,11 @@ void UnifiedMessageCenterView::SetMaxHeight(int max_height) {
Update(); Update();
} }
void UnifiedMessageCenterView::ShowClearAllAnimation() {
message_list_view_->ClearAllClosableNotifications(
scroller_->GetVisibleRect());
}
void UnifiedMessageCenterView::SetNotifications( void UnifiedMessageCenterView::SetNotifications(
const NotificationList::Notifications& notifications) { const NotificationList::Notifications& notifications) {
int index = message_list_view_->GetNotificationCount(); int index = message_list_view_->GetNotificationCount();
...@@ -89,7 +122,11 @@ void UnifiedMessageCenterView::Layout() { ...@@ -89,7 +122,11 @@ void UnifiedMessageCenterView::Layout() {
} }
gfx::Size UnifiedMessageCenterView::CalculatePreferredSize() const { gfx::Size UnifiedMessageCenterView::CalculatePreferredSize() const {
return scroller_->GetPreferredSize(); gfx::Size preferred_size = scroller_->GetPreferredSize();
// Hide Clear All button at the buttom from initial viewport.
preferred_size.set_height(preferred_size.height() -
3 * kUnifiedNotificationCenterSpacing);
return preferred_size;
} }
void UnifiedMessageCenterView::OnNotificationAdded(const std::string& id) { void UnifiedMessageCenterView::OnNotificationAdded(const std::string& id) {
...@@ -132,6 +169,15 @@ void UnifiedMessageCenterView::OnViewPreferredSizeChanged( ...@@ -132,6 +169,15 @@ void UnifiedMessageCenterView::OnViewPreferredSizeChanged(
static_cast<MessageView*>(observed_view)->notification_id()); static_cast<MessageView*>(observed_view)->notification_id());
} }
void UnifiedMessageCenterView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
tray_controller_->HandleClearAllAction();
}
void UnifiedMessageCenterView::OnAllNotificationsCleared() {
tray_controller_->OnClearAllAnimationEnded();
}
void UnifiedMessageCenterView::Update() { void UnifiedMessageCenterView::Update() {
SetVisible(message_list_view_->GetNotificationCount() > 0); SetVisible(message_list_view_->GetNotificationCount() > 0);
...@@ -183,9 +229,13 @@ void UnifiedMessageCenterView::UpdateNotification(const std::string& id) { ...@@ -183,9 +229,13 @@ void UnifiedMessageCenterView::UpdateNotification(const std::string& id) {
} }
void UnifiedMessageCenterView::ScrollToBottom() { void UnifiedMessageCenterView::ScrollToBottom() {
// Hide Clear All button at the buttom from initial viewport.
int max_position_without_button =
scroller_->vertical_scroll_bar()->GetMaxPosition() -
3 * kUnifiedNotificationCenterSpacing;
scroller_->ScrollToPosition( scroller_->ScrollToPosition(
const_cast<views::ScrollBar*>(scroller_->vertical_scroll_bar()), const_cast<views::ScrollBar*>(scroller_->vertical_scroll_bar()),
scroller_->GetPreferredSize().height()); max_position_without_button);
} }
} // namespace ash } // namespace ash
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "ui/message_center/message_center_observer.h" #include "ui/message_center/message_center_observer.h"
#include "ui/message_center/notification_list.h" #include "ui/message_center/notification_list.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/focus/focus_manager.h" #include "ui/views/focus/focus_manager.h"
#include "ui/views/view.h" #include "ui/views/view.h"
...@@ -23,20 +24,29 @@ class MessageCenter; ...@@ -23,20 +24,29 @@ class MessageCenter;
namespace ash { namespace ash {
class UnifiedSystemTrayController;
// Container for message list view. Acts as a controller/delegate of message // Container for message list view. Acts as a controller/delegate of message
// list view, passing data back and forth to message center. // list view, passing data back and forth to message center.
class ASH_EXPORT UnifiedMessageCenterView class ASH_EXPORT UnifiedMessageCenterView
: public views::View, : public views::View,
public message_center::MessageCenterObserver, public message_center::MessageCenterObserver,
public views::ViewObserver { public views::ViewObserver,
public views::ButtonListener,
public MessageListView::Observer {
public: public:
explicit UnifiedMessageCenterView( UnifiedMessageCenterView(UnifiedSystemTrayController* tray_controller,
message_center::MessageCenter* message_center); message_center::MessageCenter* message_center);
~UnifiedMessageCenterView() override; ~UnifiedMessageCenterView() override;
// Set the maximum height that the view can take. // Set the maximum height that the view can take.
void SetMaxHeight(int max_height); void SetMaxHeight(int max_height);
// Show the animation of clearing all notifications. After the animation is
// finished, UnifiedSystemTrayController::OnClearAllAnimationEnded() will be
// called.
void ShowClearAllAnimation();
protected: protected:
void SetNotifications( void SetNotifications(
const message_center::NotificationList::Notifications& notifications); const message_center::NotificationList::Notifications& notifications);
...@@ -53,6 +63,12 @@ class ASH_EXPORT UnifiedMessageCenterView ...@@ -53,6 +63,12 @@ class ASH_EXPORT UnifiedMessageCenterView
// views::ViewObserver: // views::ViewObserver:
void OnViewPreferredSizeChanged(views::View* observed_view) override; void OnViewPreferredSizeChanged(views::View* observed_view) override;
// views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// MessageListView::Observer:
void OnAllNotificationsCleared() override;
private: private:
void Update(); void Update();
void AddNotificationAt(const message_center::Notification& notification, void AddNotificationAt(const message_center::Notification& notification,
...@@ -62,7 +78,8 @@ class ASH_EXPORT UnifiedMessageCenterView ...@@ -62,7 +78,8 @@ class ASH_EXPORT UnifiedMessageCenterView
// Scroll the notification list to the bottom. // Scroll the notification list to the bottom.
void ScrollToBottom(); void ScrollToBottom();
message_center::MessageCenter* message_center_; UnifiedSystemTrayController* const tray_controller_;
message_center::MessageCenter* const message_center_;
views::ScrollView* const scroller_; views::ScrollView* const scroller_;
MessageListView* const message_list_view_; MessageListView* const message_list_view_;
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h" #include "chromeos/dbus/session_manager_client.h"
#include "ui/gfx/animation/slide_animation.h" #include "ui/gfx/animation/slide_animation.h"
#include "ui/message_center/message_center.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
namespace ash { namespace ash {
...@@ -137,6 +138,17 @@ void UnifiedSystemTrayController::ToggleExpanded() { ...@@ -137,6 +138,17 @@ void UnifiedSystemTrayController::ToggleExpanded() {
animation_->Show(); animation_->Show();
} }
void UnifiedSystemTrayController::HandleClearAllAction() {
// When the animation is finished, OnClearAllAnimationEnded() is called.
unified_view_->ShowClearAllAnimation();
}
void UnifiedSystemTrayController::OnClearAllAnimationEnded() {
message_center::MessageCenter::Get()->RemoveAllNotifications(
true /* by_user */,
message_center::MessageCenter::RemoveType::NON_PINNED);
}
void UnifiedSystemTrayController::BeginDrag(const gfx::Point& location) { void UnifiedSystemTrayController::BeginDrag(const gfx::Point& location) {
drag_init_point_ = location; drag_init_point_ = location;
was_expanded_ = animation_->IsShowing(); was_expanded_ = animation_->IsShowing();
......
...@@ -49,6 +49,12 @@ class ASH_EXPORT UnifiedSystemTrayController : public gfx::AnimationDelegate { ...@@ -49,6 +49,12 @@ class ASH_EXPORT UnifiedSystemTrayController : public gfx::AnimationDelegate {
void HandlePowerAction(); void HandlePowerAction();
// Toggle expanded state of UnifiedSystemTrayView. Called from the view. // Toggle expanded state of UnifiedSystemTrayView. Called from the view.
void ToggleExpanded(); void ToggleExpanded();
// Clear all notifications. It triggers animation, and does not remove
// notifications immediately. Called from the view.
void HandleClearAllAction();
// Called when notification removing animation is finished. Called from the
// view.
void OnClearAllAnimationEnded();
// Handle finger dragging and expand/collapse the view. Called from view. // Handle finger dragging and expand/collapse the view. Called from view.
void BeginDrag(const gfx::Point& location); void BeginDrag(const gfx::Point& location);
......
...@@ -122,7 +122,8 @@ UnifiedSystemTrayView::UnifiedSystemTrayView( ...@@ -122,7 +122,8 @@ UnifiedSystemTrayView::UnifiedSystemTrayView(
bool initially_expanded) bool initially_expanded)
: controller_(controller), : controller_(controller),
message_center_view_( message_center_view_(
new UnifiedMessageCenterView(message_center::MessageCenter::Get())), new UnifiedMessageCenterView(controller,
message_center::MessageCenter::Get())),
top_shortcuts_view_(new TopShortcutsView(controller_)), top_shortcuts_view_(new TopShortcutsView(controller_)),
feature_pods_container_(new FeaturePodsContainerView(initially_expanded)), feature_pods_container_(new FeaturePodsContainerView(initially_expanded)),
sliders_container_(new UnifiedSlidersContainerView(initially_expanded)), sliders_container_(new UnifiedSlidersContainerView(initially_expanded)),
...@@ -214,6 +215,10 @@ void UnifiedSystemTrayView::SetExpandedAmount(double expanded_amount) { ...@@ -214,6 +215,10 @@ void UnifiedSystemTrayView::SetExpandedAmount(double expanded_amount) {
Layout(); Layout();
} }
void UnifiedSystemTrayView::ShowClearAllAnimation() {
message_center_view_->ShowClearAllAnimation();
}
void UnifiedSystemTrayView::OnGestureEvent(ui::GestureEvent* event) { void UnifiedSystemTrayView::OnGestureEvent(ui::GestureEvent* event) {
gfx::Point screen_location = event->location(); gfx::Point screen_location = event->location();
ConvertPointToScreen(this, &screen_location); ConvertPointToScreen(this, &screen_location);
......
...@@ -77,6 +77,8 @@ class ASH_EXPORT UnifiedSystemTrayView : public views::View { ...@@ -77,6 +77,8 @@ class ASH_EXPORT UnifiedSystemTrayView : public views::View {
// Otherwise, it shows intermediate state. // Otherwise, it shows intermediate state.
void SetExpandedAmount(double expanded_amount); void SetExpandedAmount(double expanded_amount);
void ShowClearAllAnimation();
// views::View: // views::View:
void OnGestureEvent(ui::GestureEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
void ChildPreferredSizeChanged(views::View* child) override; void ChildPreferredSizeChanged(views::View* child) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment