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 @@
namespace ash {
SignOutButton::SignOutButton(views::ButtonListener* listener)
: views::LabelButton(listener,
user::GetLocalizedSignOutStringForStatus(
Shell::Get()->session_controller()->login_status(),
false /* multiline */)) {
SetVisible(Shell::Get()->session_controller()->login_status() !=
LoginStatus::NOT_LOGGED_IN);
RoundedLabelButton::RoundedLabelButton(views::ButtonListener* listener,
const base::string16& text)
: views::LabelButton(listener, text) {
SetEnabledTextColors(kUnifiedMenuTextColor);
SetHorizontalAlignment(gfx::ALIGN_CENTER);
SetBorder(views::CreateEmptyBorder(gfx::Insets()));
......@@ -34,18 +29,18 @@ SignOutButton::SignOutButton(views::ButtonListener* listener)
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,
kTrayItemSize);
}
int SignOutButton::GetHeightForWidth(int width) const {
int RoundedLabelButton::GetHeightForWidth(int width) const {
return kTrayItemSize;
}
void SignOutButton::PaintButtonContents(gfx::Canvas* canvas) {
void RoundedLabelButton::PaintButtonContents(gfx::Canvas* canvas) {
gfx::Rect rect(GetContentsBounds());
cc::PaintFlags flags;
flags.setAntiAlias(true);
......@@ -56,26 +51,38 @@ void SignOutButton::PaintButtonContents(gfx::Canvas* canvas) {
views::LabelButton::PaintButtonContents(canvas);
}
std::unique_ptr<views::InkDrop> SignOutButton::CreateInkDrop() {
std::unique_ptr<views::InkDrop> RoundedLabelButton::CreateInkDrop() {
return TrayPopupUtils::CreateInkDrop(this);
}
std::unique_ptr<views::InkDropRipple> SignOutButton::CreateInkDropRipple()
std::unique_ptr<views::InkDropRipple> RoundedLabelButton::CreateInkDropRipple()
const {
return TrayPopupUtils::CreateInkDropRipple(
TrayPopupInkDropStyle::FILL_BOUNDS, this,
GetInkDropCenterBasedOnLastEvent(), kUnifiedMenuIconColor);
}
std::unique_ptr<views::InkDropHighlight> SignOutButton::CreateInkDropHighlight()
const {
std::unique_ptr<views::InkDropHighlight>
RoundedLabelButton::CreateInkDropHighlight() const {
return TrayPopupUtils::CreateInkDropHighlight(
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(),
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
......@@ -9,13 +9,12 @@
namespace ash {
// 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 views::LabelButton {
// LabelButton that has rounded shape with Material Design ink drop.
class RoundedLabelButton : public views::LabelButton {
public:
SignOutButton(views::ButtonListener* listener);
~SignOutButton() override;
RoundedLabelButton(views::ButtonListener* listener,
const base::string16& text);
~RoundedLabelButton() override;
// views::LabelButton:
gfx::Size CalculatePreferredSize() const override;
......@@ -27,6 +26,18 @@ class SignOutButton : public views::LabelButton {
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:
DISALLOW_COPY_AND_ASSIGN(SignOutButton);
};
......
......@@ -4,13 +4,18 @@
#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/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_types.h"
#include "ui/message_center/views/message_view.h"
#include "ui/message_center/views/message_view_factory.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
#include "ui/views/layout/box_layout.h"
using message_center::MessageCenter;
using message_center::MessageView;
......@@ -29,8 +34,10 @@ const int kMaxVisibleNotifications = 100;
// ///////////////////////////////////////////////////////////
UnifiedMessageCenterView::UnifiedMessageCenterView(
UnifiedSystemTrayController* tray_controller,
MessageCenter* message_center)
: message_center_(message_center),
: tray_controller_(tray_controller),
message_center_(message_center),
scroller_(new views::ScrollView()),
message_list_view_(new MessageListView()) {
SetPaintToLayer();
......@@ -48,11 +55,32 @@ UnifiedMessageCenterView::UnifiedMessageCenterView(
scroller_->set_draw_overflow_indicator(false);
AddChildView(scroller_);
message_list_view_->SetBorder(
views::CreateEmptyBorder(0, 0, kUnifiedNotificationCenterSpacing, 0));
message_list_view_->set_use_fixed_height(false);
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());
}
......@@ -66,6 +94,11 @@ void UnifiedMessageCenterView::SetMaxHeight(int max_height) {
Update();
}
void UnifiedMessageCenterView::ShowClearAllAnimation() {
message_list_view_->ClearAllClosableNotifications(
scroller_->GetVisibleRect());
}
void UnifiedMessageCenterView::SetNotifications(
const NotificationList::Notifications& notifications) {
int index = message_list_view_->GetNotificationCount();
......@@ -89,7 +122,11 @@ void UnifiedMessageCenterView::Layout() {
}
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) {
......@@ -132,6 +169,15 @@ void UnifiedMessageCenterView::OnViewPreferredSizeChanged(
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() {
SetVisible(message_list_view_->GetNotificationCount() > 0);
......@@ -183,9 +229,13 @@ void UnifiedMessageCenterView::UpdateNotification(const std::string& id) {
}
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(
const_cast<views::ScrollBar*>(scroller_->vertical_scroll_bar()),
scroller_->GetPreferredSize().height());
max_position_without_button);
}
} // namespace ash
......@@ -12,6 +12,7 @@
#include "base/macros.h"
#include "ui/message_center/message_center_observer.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/view.h"
......@@ -23,20 +24,29 @@ class MessageCenter;
namespace ash {
class UnifiedSystemTrayController;
// Container for message list view. Acts as a controller/delegate of message
// list view, passing data back and forth to message center.
class ASH_EXPORT UnifiedMessageCenterView
: public views::View,
public message_center::MessageCenterObserver,
public views::ViewObserver {
public views::ViewObserver,
public views::ButtonListener,
public MessageListView::Observer {
public:
explicit UnifiedMessageCenterView(
UnifiedMessageCenterView(UnifiedSystemTrayController* tray_controller,
message_center::MessageCenter* message_center);
~UnifiedMessageCenterView() override;
// Set the maximum height that the view can take.
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:
void SetNotifications(
const message_center::NotificationList::Notifications& notifications);
......@@ -53,6 +63,12 @@ class ASH_EXPORT UnifiedMessageCenterView
// views::ViewObserver:
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:
void Update();
void AddNotificationAt(const message_center::Notification& notification,
......@@ -62,7 +78,8 @@ class ASH_EXPORT UnifiedMessageCenterView
// Scroll the notification list to the bottom.
void ScrollToBottom();
message_center::MessageCenter* message_center_;
UnifiedSystemTrayController* const tray_controller_;
message_center::MessageCenter* const message_center_;
views::ScrollView* const scroller_;
MessageListView* const message_list_view_;
......
......@@ -42,6 +42,7 @@
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/message_center/message_center.h"
#include "ui/views/widget/widget.h"
namespace ash {
......@@ -137,6 +138,17 @@ void UnifiedSystemTrayController::ToggleExpanded() {
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) {
drag_init_point_ = location;
was_expanded_ = animation_->IsShowing();
......
......@@ -49,6 +49,12 @@ class ASH_EXPORT UnifiedSystemTrayController : public gfx::AnimationDelegate {
void HandlePowerAction();
// Toggle expanded state of UnifiedSystemTrayView. Called from the view.
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.
void BeginDrag(const gfx::Point& location);
......
......@@ -122,7 +122,8 @@ UnifiedSystemTrayView::UnifiedSystemTrayView(
bool initially_expanded)
: controller_(controller),
message_center_view_(
new UnifiedMessageCenterView(message_center::MessageCenter::Get())),
new UnifiedMessageCenterView(controller,
message_center::MessageCenter::Get())),
top_shortcuts_view_(new TopShortcutsView(controller_)),
feature_pods_container_(new FeaturePodsContainerView(initially_expanded)),
sliders_container_(new UnifiedSlidersContainerView(initially_expanded)),
......@@ -214,6 +215,10 @@ void UnifiedSystemTrayView::SetExpandedAmount(double expanded_amount) {
Layout();
}
void UnifiedSystemTrayView::ShowClearAllAnimation() {
message_center_view_->ShowClearAllAnimation();
}
void UnifiedSystemTrayView::OnGestureEvent(ui::GestureEvent* event) {
gfx::Point screen_location = event->location();
ConvertPointToScreen(this, &screen_location);
......
......@@ -77,6 +77,8 @@ class ASH_EXPORT UnifiedSystemTrayView : public views::View {
// Otherwise, it shows intermediate state.
void SetExpandedAmount(double expanded_amount);
void ShowClearAllAnimation();
// views::View:
void OnGestureEvent(ui::GestureEvent* event) 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