Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1242)

Unified Diff: ash/system/web_notification/web_notification_tray.cc

Issue 10824153: Change Ash web notification behavior (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix clang Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ash/system/web_notification/web_notification_tray.cc
diff --git a/ash/system/web_notification/web_notification_tray.cc b/ash/system/web_notification/web_notification_tray.cc
index c94e48c881fedf90da99b12db5e824a6a646ddc9..823d3f4f16dfbb0afcdd051ade3248831965acfb 100644
--- a/ash/system/web_notification/web_notification_tray.cc
+++ b/ash/system/web_notification/web_notification_tray.cc
@@ -5,11 +5,15 @@
#include "ash/system/web_notification/web_notification_tray.h"
#include "ash/system/status_area_widget.h"
+#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/tray_bubble_view.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_views.h"
#include "base/bind.h"
#include "base/message_loop.h"
+#include "base/stringprintf.h"
+#include "base/timer.h"
+#include "base/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "ui/aura/window.h"
@@ -38,9 +42,10 @@ const int kTrayContainerVerticalPaddingVerticalAlignment = 1;
const int kTrayContainerHorizontalPaddingVerticalAlignment = 0;
const int kPaddingFromLeftEdgeOfSystemTrayBottomAlignment = 8;
const int kPaddingFromTopEdgeOfSystemTrayVerticalAlignment = 10;
-const int kNotificationImageIconWidth = 40;
-const int kNotificationImageIconHeight = 25;
-const int kNotificationImageIconInset = 4;
+const int kTrayWidth = 40;
+const int kTrayHeight = 32;
+const int kTraySideWidth = 32;
+const int kTraySideHeight = 24;
// Web Notification Bubble constants
const int kWebNotificationBubbleMinHeight = 80;
@@ -50,6 +55,7 @@ const int kWebNotificationBubbleMaxHeight = 480;
const int kUpdateDelayMs = 50;
// Limit the number of visible notifications.
const int kMaxVisibleNotifications = 100;
+const int kAutocloseDelaySeconds = 5;
// Individual notifications constants
const int kWebNotificationWidth = 320;
@@ -61,20 +67,10 @@ const int kTogglePermissionCommand = 0;
const int kToggleExtensionCommand = 1;
const int kShowSettingsCommand = 2;
-// The image has three icons: 1 notifiaction, 2 notifications, and 3+.
-gfx::ImageSkia GetNotificationImage(int notification_count) {
- const gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().
- GetImageSkiaNamed(IDR_AURA_UBER_TRAY_WEB_NOTIFICATON);
- int image_index = notification_count - 1;
- image_index = std::max(0, std::min(image_index, 2));
- // The original width of the image looks too big, so we need to inset
- // it somewhat.
- gfx::Rect region(
- kNotificationImageIconInset,
- image_index * kNotificationImageIconHeight,
- kNotificationImageIconWidth - 2 * kNotificationImageIconInset,
- kNotificationImageIconHeight);
- return gfx::ImageSkiaOperations::ExtractSubset(*image, region);
+std::string GetNotificationText(int notification_count) {
+ if (notification_count >= 100)
+ return "99+";
+ return base::StringPrintf("%d", notification_count);
}
} // namespace
@@ -484,15 +480,21 @@ class WebNotificationButtonView : public views::View,
DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonView);
};
-} // namespace internal
+class WebContentsView : public views::View {
+ public:
+ WebContentsView() {}
+ virtual ~WebContentsView() {}
-using internal::TrayBubbleView;
-using internal::WebNotificationList;
-using internal::WebNotificationView;
+ virtual void Update(
+ const WebNotificationList::Notifications& notifications) = 0;
-class WebNotificationTray::BubbleContentsView : public views::View {
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WebContentsView);
+};
+
+class MessageCenterContentsView : public WebContentsView {
public:
- explicit BubbleContentsView(WebNotificationTray* tray)
+ explicit MessageCenterContentsView(WebNotificationTray* tray)
: tray_(tray) {
set_border(views::Border::CreateSolidSidedBorder(
1, 1, 1, 1, ash::kBorderDarkColor));
@@ -545,14 +547,59 @@ class WebNotificationTray::BubbleContentsView : public views::View {
views::View* scroll_content_;
internal::WebNotificationButtonView* button_view_;
- DISALLOW_COPY_AND_ASSIGN(BubbleContentsView);
+ DISALLOW_COPY_AND_ASSIGN(MessageCenterContentsView);
};
+class WebNotificationContentsView : public WebContentsView {
+ public:
+ explicit WebNotificationContentsView(WebNotificationTray* tray)
+ : tray_(tray) {
+ set_border(views::Border::CreateSolidSidedBorder(
+ 1, 1, 1, 1, ash::kBorderDarkColor));
+
+ SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
+ set_background(views::Background::CreateSolidBackground(kBackgroundColor));
+
+ content_ = new views::View;
+ content_->SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
+ AddChildView(content_);
+ }
+
+ void Update(const WebNotificationList::Notifications& notifications) {
+ content_->RemoveAllChildViews(true);
+ WebNotificationList::Notifications::const_iterator iter =
+ notifications.begin();
+ WebNotificationView* view = new WebNotificationView(tray_, *iter);
+ content_->AddChildView(view);
+ GetWidget()->GetRootView()->SchedulePaint();
+ }
+
+ private:
+ WebNotificationTray* tray_;
+ views::View* content_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebNotificationContentsView);
+};
+
+} // namespace internal
+
+using internal::TrayBubbleView;
+using internal::WebNotificationList;
+using internal::WebContentsView;
+
class WebNotificationTray::Bubble : public TrayBubbleView::Host,
public views::WidgetObserver {
public:
- explicit Bubble(WebNotificationTray* tray)
+ enum BubbleType {
+ BUBBLE_TYPE_MESAGE_CENTER,
+ BUBBLE_TYPE_NOTIFICATION
+ };
+
+ Bubble(WebNotificationTray* tray, BubbleType bubble_type)
: tray_(tray),
+ bubble_type_(bubble_type),
bubble_view_(NULL),
bubble_widget_(NULL),
contents_view_(NULL),
@@ -561,7 +608,12 @@ class WebNotificationTray::Bubble : public TrayBubbleView::Host,
TrayBubbleView::InitParams init_params(TrayBubbleView::ANCHOR_TYPE_TRAY,
tray->shelf_alignment());
init_params.bubble_width = kWebNotificationWidth;
- init_params.max_height = kWebNotificationBubbleMaxHeight;
+ if (bubble_type == BUBBLE_TYPE_MESAGE_CENTER) {
+ init_params.max_height = kWebNotificationBubbleMaxHeight;
+ } else {
+ init_params.arrow_color = kBackgroundColor;
+ init_params.close_on_deactivate = false;
+ }
if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) {
gfx::Point bounds(anchor->width() / 2, 0);
ConvertPointToWidget(anchor, &bounds);
@@ -569,7 +621,10 @@ class WebNotificationTray::Bubble : public TrayBubbleView::Host,
}
bubble_view_ = TrayBubbleView::Create(anchor, this, init_params);
- contents_view_ = new BubbleContentsView(tray);
+ if (bubble_type == BUBBLE_TYPE_MESAGE_CENTER)
+ contents_view_ = new internal::MessageCenterContentsView(tray);
+ else
+ contents_view_ = new internal::WebNotificationContentsView(tray);
bubble_view_->AddChildView(contents_view_);
bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
@@ -590,6 +645,8 @@ class WebNotificationTray::Bubble : public TrayBubbleView::Host,
}
void ScheduleUpdate() {
+ StartAutoCloseTimer();
+
weak_ptr_factory_.InvalidateWeakPtrs(); // Cancel any pending update.
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
@@ -607,34 +664,60 @@ class WebNotificationTray::Bubble : public TrayBubbleView::Host,
}
virtual void OnMouseEnteredView() OVERRIDE {
+ StopAutoCloseTimer();
}
virtual void OnMouseExitedView() OVERRIDE {
+ StartAutoCloseTimer();
}
virtual void OnClickedOutsideView() OVERRIDE {
// May delete |this|.
- tray_->status_area_widget()->HideWebNotificationBubble();
+ tray_->HideMessageCenterBubble();
}
// Overridden from views::WidgetObserver:
virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE {
CHECK_EQ(bubble_widget_, widget);
bubble_widget_ = NULL;
- tray_->HideBubble(); // Will destroy |this|.
+ tray_->HideBubble(this); // Will destroy |this|.
}
private:
void UpdateBubbleView() {
- contents_view_->Update(tray_->notification_list()->notifications());
+ const WebNotificationList::Notifications& notifications =
+ tray_->notification_list()->notifications();
+ if (notifications.size() == 0) {
+ tray_->HideBubble(this); // deletes |this|!
+ return;
+ }
+ contents_view_->Update(notifications);
bubble_view_->Show();
bubble_view_->UpdateBubble();
}
+ void StartAutoCloseTimer() {
+ if (bubble_type_ != BUBBLE_TYPE_NOTIFICATION)
+ return;
+ autoclose_.Start(FROM_HERE,
+ base::TimeDelta::FromSeconds(kAutocloseDelaySeconds),
+ this, &Bubble::OnAutoClose);
+ }
+
+ void StopAutoCloseTimer() {
+ autoclose_.Stop();
+ }
+
+ void OnAutoClose() {
+ tray_->HideBubble(this); // deletes |this|!
+ }
+
WebNotificationTray* tray_;
+ BubbleType bubble_type_;
TrayBubbleView* bubble_view_;
views::Widget* bubble_widget_;
- BubbleContentsView* contents_view_;
+ WebContentsView* contents_view_;
+ base::OneShotTimer<Bubble> autoclose_;
base::WeakPtrFactory<Bubble> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(Bubble);
@@ -642,20 +725,22 @@ class WebNotificationTray::Bubble : public TrayBubbleView::Host,
WebNotificationTray::WebNotificationTray(
internal::StatusAreaWidget* status_area_widget)
- : status_area_widget_(status_area_widget),
+ : internal::TrayBackgroundView(status_area_widget),
notification_list_(new WebNotificationList()),
- tray_container_(NULL),
- icon_(NULL),
+ count_label_(NULL),
delegate_(NULL),
- show_bubble_on_unlock_(false) {
- tray_container_ = new views::View;
- SetShelfAlignment(shelf_alignment());
-
- icon_ = new views::ImageView;
- tray_container_->AddChildView(icon_);
- UpdateIcon(); // Hides the tray initially.
-
- SetContents(tray_container_);
+ show_message_center_on_unlock_(false),
+ unread_count_(0) {
+ count_label_ = new views::Label(UTF8ToUTF16("0"));
+ internal::SetupLabelForTray(count_label_);
+ gfx::Font font = count_label_->font();
+ count_label_->SetFont(font.DeriveFont(0, font.GetStyle() & ~gfx::Font::BOLD));
+ count_label_->SetHorizontalAlignment(views::Label::ALIGN_CENTER);
+
+ tray_container()->set_size(gfx::Size(kTrayWidth, kTrayHeight));
+ tray_container()->AddChildView(count_label_);
+
+ UpdateTray();
}
WebNotificationTray::~WebNotificationTray() {
@@ -673,21 +758,18 @@ void WebNotificationTray::AddNotification(const std::string& id,
const std::string& extension_id) {
notification_list_->AddNotification(
id, title, message, display_source, extension_id);
- UpdateIcon();
- if (bubble()) {
- bubble_->ScheduleUpdate();
- } else {
- status_area_widget_->ShowWebNotificationBubble(
- internal::StatusAreaWidget::NON_USER_ACTION);
- }
+ if (!message_center_bubble())
+ ++unread_count_;
+ UpdateTrayAndBubble();
+ if (!message_center_bubble())
+ ShowNotificationBubble();
}
void WebNotificationTray::UpdateNotification(const std::string& id,
const string16& title,
const string16& message) {
notification_list_->UpdateNotificationMessage(id, title, message);
- if (bubble())
- bubble_->ScheduleUpdate();
+ UpdateTrayAndBubble();
}
void WebNotificationTray::RemoveNotification(const std::string& id) {
@@ -695,7 +777,7 @@ void WebNotificationTray::RemoveNotification(const std::string& id) {
return;
if (delegate_)
delegate_->NotificationRemoved(id);
- UpdateBubbleAndIcon();
+ UpdateTrayAndBubble();
}
void WebNotificationTray::RemoveAllNotifications() {
@@ -712,22 +794,21 @@ void WebNotificationTray::RemoveAllNotifications() {
}
}
notification_list_->RemoveAllNotifications();
- UpdateBubbleAndIcon();
+ UpdateTrayAndBubble();
}
void WebNotificationTray::SetNotificationImage(const std::string& id,
const gfx::ImageSkia& image) {
if (!notification_list_->SetNotificationImage(id, image))
return;
- if (bubble())
- bubble_->ScheduleUpdate();
+ UpdateTrayAndBubble();
}
void WebNotificationTray::DisableByExtension(const std::string& id) {
// When we disable notifications, we remove any existing matching
// notifications to avoid adding complicated UI to re-enable the source.
notification_list_->RemoveNotificationsByExtension(id);
- UpdateBubbleAndIcon();
+ UpdateTrayAndBubble();
if (delegate_)
delegate_->DisableExtension(id);
}
@@ -735,38 +816,63 @@ void WebNotificationTray::DisableByExtension(const std::string& id) {
void WebNotificationTray::DisableByUrl(const std::string& id) {
// See comment for DisableByExtension.
notification_list_->RemoveNotificationsBySource(id);
- UpdateBubbleAndIcon();
+ UpdateTrayAndBubble();
if (delegate_)
delegate_->DisableNotificationsFromSource(id);
}
-void WebNotificationTray::ShowBubble() {
- if (status_area_widget_->login_status() == user::LOGGED_IN_LOCKED) {
- show_bubble_on_unlock_ = true;
+void WebNotificationTray::ShowMessageCenterBubble() {
+ if (status_area_widget()->login_status() == user::LOGGED_IN_LOCKED)
return;
- }
- if (bubble())
+ unread_count_ = 0;
+ UpdateTray();
+ if (message_center_bubble())
return;
- bubble_.reset(new Bubble(this));
+ if (GetNotificationCount() == 0)
+ return;
+ notification_bubble_.reset();
+ message_center_bubble_.reset(
+ new Bubble(this, Bubble::BUBBLE_TYPE_MESAGE_CENTER));
+ status_area_widget()->SetHideSystemNotifications(true);
+}
+
+void WebNotificationTray::HideMessageCenterBubble() {
+ message_center_bubble_.reset();
+ show_message_center_on_unlock_ = false;
+ status_area_widget()->SetHideSystemNotifications(false);
+}
+
+void WebNotificationTray::ShowNotificationBubble() {
+ if (status_area_widget()->login_status() == user::LOGGED_IN_LOCKED)
+ return;
+ if (message_center_bubble())
+ return;
+ if (!status_area_widget()->ShouldShowNonSystemNotifications())
+ return;
+ UpdateTray();
+ notification_bubble_.reset(
+ new Bubble(this, Bubble::BUBBLE_TYPE_NOTIFICATION));
}
-void WebNotificationTray::HideBubble() {
- bubble_.reset();
- show_bubble_on_unlock_ = false;
+void WebNotificationTray::HideNotificationBubble() {
+ notification_bubble_.reset();
}
void WebNotificationTray::UpdateAfterLoginStatusChange(
user::LoginStatus login_status) {
if (login_status == user::LOGGED_IN_LOCKED) {
- if (bubble()) {
- HideBubble();
- show_bubble_on_unlock_ = true;
+ if (message_center_bubble()) {
+ message_center_bubble_.reset();
+ show_message_center_on_unlock_ = true;
}
- } else if (show_bubble_on_unlock_) {
- ShowBubble();
- show_bubble_on_unlock_ = false;
+ if (notification_bubble())
+ notification_bubble_.reset();
+ } else {
+ if (show_message_center_on_unlock_)
+ ShowMessageCenterBubble();
+ show_message_center_on_unlock_ = false;
}
- UpdateIcon();
+ UpdateTray();
}
void WebNotificationTray::ShowSettings(const std::string& id) {
@@ -780,89 +886,55 @@ void WebNotificationTray::OnClicked(const std::string& id) {
}
void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) {
+ if (alignment == shelf_alignment())
+ return;
internal::TrayBackgroundView::SetShelfAlignment(alignment);
- SetTrayContainerBorder();
- SetBorder();
- tray_container_->SetLayoutManager(new views::BoxLayout(
- alignment == SHELF_ALIGNMENT_BOTTOM ?
- views::BoxLayout::kHorizontal : views::BoxLayout::kVertical,
- 0, 0, 0));
+ if (alignment == SHELF_ALIGNMENT_BOTTOM)
+ tray_container()->set_size(gfx::Size(kTrayWidth, kTrayHeight));
+ else
+ tray_container()->set_size(gfx::Size(kTraySideWidth, kTraySideHeight));
// Destroy any existing bubble so that it will be rebuilt correctly.
- bubble_.reset();
+ message_center_bubble_.reset();
+ notification_bubble_.reset();
}
bool WebNotificationTray::PerformAction(const views::Event& event) {
- if (bubble()) {
- status_area_widget_->HideWebNotificationBubble();
- } else {
- status_area_widget_->ShowWebNotificationBubble(
- internal::StatusAreaWidget::USER_ACTION);
- }
+ if (message_center_bubble())
+ HideMessageCenterBubble();
+ else
+ ShowMessageCenterBubble();
return true;
}
-void WebNotificationTray::SetBorder() {
- // Change the border padding for different shelf alignment.
- // This affects the position of the web notification tray.
- if (shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) {
- set_border(views::Border::CreateEmptyBorder(0, 0,
- kPaddingFromBottomOfScreenBottomAlignment,
- kPaddingFromLeftEdgeOfSystemTrayBottomAlignment));
- } else if (shelf_alignment() == SHELF_ALIGNMENT_LEFT) {
- set_border(views::Border::CreateEmptyBorder(0,
- kPaddingFromOuterEdgeOfLauncherVerticalAlignment,
- kPaddingFromTopEdgeOfSystemTrayVerticalAlignment,
- kPaddingFromInnerEdgeOfLauncherVerticalAlignment));
- } else {
- set_border(views::Border::CreateEmptyBorder(0,
- kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
- kPaddingFromTopEdgeOfSystemTrayVerticalAlignment,
- kPaddingFromOuterEdgeOfLauncherVerticalAlignment));
- }
-}
-
-void WebNotificationTray::SetTrayContainerBorder() {
- // Adjust the size of web notification tray dark background by adding
- // additional empty border.
- if (shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) {
- tray_container_->set_border(views::Border::CreateEmptyBorder(
- kTrayContainerVeritcalPaddingBottomAlignment,
- kTrayContainerHorizontalPaddingBottomAlignment,
- kTrayContainerVeritcalPaddingBottomAlignment,
- kTrayContainerHorizontalPaddingBottomAlignment));
- } else {
- tray_container_->set_border(views::Border::CreateEmptyBorder(
- kTrayContainerVerticalPaddingVerticalAlignment,
- kTrayContainerHorizontalPaddingVerticalAlignment,
- kTrayContainerVerticalPaddingVerticalAlignment,
- kTrayContainerHorizontalPaddingVerticalAlignment));
- }
-}
-
int WebNotificationTray::GetNotificationCount() const {
return notification_list()->notifications().size();
}
-void WebNotificationTray::UpdateIcon() {
- int count = GetNotificationCount();
- if (count == 0 ||
- status_area_widget_->login_status() == user::LOGGED_IN_LOCKED) {
- SetVisible(false);
- } else {
- icon_->SetImage(GetNotificationImage(count));
- SetVisible(true);
- }
- PreferredSizeChanged();
+void WebNotificationTray::UpdateTray() {
+ count_label_->SetText(UTF8ToUTF16(GetNotificationText(unread_count_)));
+ Layout();
+ SchedulePaint();
}
-void WebNotificationTray::UpdateBubbleAndIcon() {
- UpdateIcon();
- if (!bubble())
+void WebNotificationTray::UpdateTrayAndBubble() {
+ UpdateTray();
+ if (GetNotificationCount() == 0) {
+ HideMessageCenterBubble();
+ notification_bubble_.reset();
return;
- if (GetNotificationCount() == 0)
- status_area_widget_->HideWebNotificationBubble();
- else
- bubble_->ScheduleUpdate();
+ }
+ if (message_center_bubble())
+ message_center_bubble()->ScheduleUpdate();
+ if (notification_bubble())
+ notification_bubble()->ScheduleUpdate();
+}
+
+void WebNotificationTray::HideBubble(Bubble* bubble) {
+ if (bubble == message_center_bubble()) {
+ HideMessageCenterBubble();
+ } else if (bubble == notification_bubble()) {
+ notification_bubble_.reset();
+ }
}
} // namespace ash
« no previous file with comments | « ash/system/web_notification/web_notification_tray.h ('k') | ash/system/web_notification/web_notification_tray_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698