summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/system/web_notification/web_notification_tray_unittest.cc8
-rw-r--r--chrome/browser/extensions/api/notifications/notifications_apitest.cc12
-rw-r--r--chrome/browser/extensions/extension_crash_recovery_browsertest.cc6
-rw-r--r--chrome/browser/notifications/message_center_notification_manager.cc2
-rw-r--r--chrome/browser/ui/views/message_center/web_notification_tray_win_browsertest.cc5
-rw-r--r--ui/message_center/message_center.cc44
-rw-r--r--ui/message_center/message_center.gyp1
-rw-r--r--ui/message_center/message_center.h37
-rw-r--r--ui/message_center/message_center_tray.h2
-rw-r--r--ui/message_center/notification.cc3
-rw-r--r--ui/message_center/notification.h21
-rw-r--r--ui/message_center/notification_change_observer.h35
-rw-r--r--ui/message_center/notification_list.cc11
-rw-r--r--ui/message_center/notification_list.h28
-rw-r--r--ui/message_center/notification_list_unittest.cc29
-rw-r--r--ui/message_center/views/message_bubble_base.cc4
-rw-r--r--ui/message_center/views/message_bubble_base.h8
-rw-r--r--ui/message_center/views/message_center_bubble.cc276
-rw-r--r--ui/message_center/views/message_center_bubble.h29
-rw-r--r--ui/message_center/views/message_popup_bubble.cc25
-rw-r--r--ui/message_center/views/message_popup_bubble.h5
-rw-r--r--ui/message_center/views/message_popup_collection.cc26
-rw-r--r--ui/message_center/views/message_popup_collection.h12
-rw-r--r--ui/message_center/views/message_simple_view.cc10
-rw-r--r--ui/message_center/views/message_simple_view.h6
-rw-r--r--ui/message_center/views/message_view.cc67
-rw-r--r--ui/message_center/views/message_view.h34
-rw-r--r--ui/message_center/views/notification_view.cc227
-rw-r--r--ui/message_center/views/notification_view.h31
-rw-r--r--ui/message_center/views/notifier_settings_view.cc2
-rw-r--r--ui/message_center/views/notifier_settings_view.h4
31 files changed, 606 insertions, 404 deletions
diff --git a/ash/system/web_notification/web_notification_tray_unittest.cc b/ash/system/web_notification/web_notification_tray_unittest.cc
index b58845c..7895d18 100644
--- a/ash/system/web_notification/web_notification_tray_unittest.cc
+++ b/ash/system/web_notification/web_notification_tray_unittest.cc
@@ -74,6 +74,10 @@ class TestDelegate : public message_center::MessageCenter::Delegate {
virtual void OnClicked(const std::string& notifcation_id) OVERRIDE {
}
+ virtual void OnButtonClicked(const std::string& id,
+ int button_index) OVERRIDE {
+ }
+
void AddNotification(WebNotificationTray* tray, const std::string& id) {
notification_ids_.insert(id);
get_message_center()->AddNotification(
@@ -222,10 +226,8 @@ TEST_F(WebNotificationTrayTest, ManyPopupNotifications) {
EXPECT_EQ(notifications_to_add,
get_message_center()->NotificationCount());
if (message_center::IsRichNotificationEnabled()) {
- NotificationList::Delegate* list_delegate =
- tray->popup_collection_.get()->list_delegate_;
NotificationList::PopupNotifications popups =
- list_delegate->GetNotificationList()->GetPopupNotifications();
+ get_message_center()->notification_list()->GetPopupNotifications();
EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications, popups.size());
} else {
EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications,
diff --git a/chrome/browser/extensions/api/notifications/notifications_apitest.cc b/chrome/browser/extensions/api/notifications/notifications_apitest.cc
index 523643d..27bb6f3 100644
--- a/chrome/browser/extensions/api/notifications/notifications_apitest.cc
+++ b/chrome/browser/extensions/api/notifications/notifications_apitest.cc
@@ -283,18 +283,6 @@ IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestByUser) {
true);
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
-
- {
- ResultCatcher catcher;
- g_browser_process->message_center()->SendRemoveAllNotifications(false);
- EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
- }
-
- {
- ResultCatcher catcher;
- g_browser_process->message_center()->SendRemoveAllNotifications(true);
- EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
- }
}
#endif
diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
index 220885c..af461a7 100644
--- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
+++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
@@ -125,11 +125,11 @@ class MessageCenterExtensionCrashRecoveryTest
message_center::MessageCenter::Get();
ASSERT_GT(message_center->NotificationCount(), index);
message_center::NotificationList::Notifications::reverse_iterator it =
- message_center->GetNotificationList()->GetNotifications().rbegin();
+ message_center->notification_list()->GetNotifications().rbegin();
for (size_t i=0; i < index; ++i)
it++;
std::string id = (*it)->id();
- message_center->OnNotificationClicked(id);
+ message_center->OnClicked(id);
WaitForExtensionLoad();
}
@@ -138,7 +138,7 @@ class MessageCenterExtensionCrashRecoveryTest
message_center::MessageCenter::Get();
ASSERT_GT(message_center->NotificationCount(), index);
message_center::NotificationList::Notifications::reverse_iterator it =
- message_center->GetNotificationList()->GetNotifications().rbegin();
+ message_center->notification_list()->GetNotifications().rbegin();
for (size_t i=0; i < index; i++) { it++; }
ASSERT_TRUE(
g_browser_process->notification_ui_manager()->CancelById((*it)->id()));
diff --git a/chrome/browser/notifications/message_center_notification_manager.cc b/chrome/browser/notifications/message_center_notification_manager.cc
index 347f26b..38d1995 100644
--- a/chrome/browser/notifications/message_center_notification_manager.cc
+++ b/chrome/browser/notifications/message_center_notification_manager.cc
@@ -141,7 +141,7 @@ bool MessageCenterNotificationManager::UpdateNotification(
old_notification->profile()->IsSameProfile(profile)) {
std::string old_id =
old_notification->notification().notification_id();
- DCHECK(message_center_->GetNotificationList()->HasNotification(old_id));
+ DCHECK(message_center_->notification_list()->HasNotification(old_id));
// Add/remove notification in the local list but just update the same
// one in MessageCenter.
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray_win_browsertest.cc b/chrome/browser/ui/views/message_center/web_notification_tray_win_browsertest.cc
index b7c9c39..efe5429 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray_win_browsertest.cc
+++ b/chrome/browser/ui/views/message_center/web_notification_tray_win_browsertest.cc
@@ -52,9 +52,10 @@ class TestDelegate : public message_center::MessageCenter::Delegate {
virtual void DisableExtension(const std::string& notification_id) OVERRIDE { }
virtual void ShowSettings(const std::string& notification_id) OVERRIDE { }
- virtual void OnClicked(const std::string& notification_id) OVERRIDE { }
virtual void ShowSettingsDialog(gfx::NativeView context) OVERRIDE { }
-
+ virtual void OnClicked(const std::string& notification_id) OVERRIDE { }
+ virtual void OnButtonClicked(const std::string& id,
+ int button_index) OVERRIDE {}
void AddNotification(const std::string& id) {
notification_ids_.insert(id);
diff --git a/ui/message_center/message_center.cc b/ui/message_center/message_center.cc
index 29492a8..9f67ecd 100644
--- a/ui/message_center/message_center.cc
+++ b/ui/message_center/message_center.cc
@@ -36,6 +36,12 @@ void MessageCenter::Shutdown() {
}
//------------------------------------------------------------------------------
+
+MessageCenter::Delegate::~Delegate() {
+}
+
+//------------------------------------------------------------------------------
+
MessageCenter::MessageCenter()
: delegate_(NULL) {
notification_list_.reset(new NotificationList(this));
@@ -126,15 +132,14 @@ void MessageCenter::SetNotificationButtonIcon(
}
//------------------------------------------------------------------------------
-// Overridden from NotificationList::Delegate.
+// Overridden from NotificationChangeObserver:
-void MessageCenter::SendRemoveNotification(const std::string& id,
- bool by_user) {
+void MessageCenter::OnRemoveNotification(const std::string& id, bool by_user) {
if (delegate_)
delegate_->NotificationRemoved(id, by_user);
}
-void MessageCenter::SendRemoveAllNotifications(bool by_user) {
+void MessageCenter::OnRemoveAllNotifications(bool by_user) {
if (delegate_) {
const NotificationList::Notifications& notifications =
notification_list_->GetNotifications();
@@ -149,7 +154,7 @@ void MessageCenter::SendRemoveAllNotifications(bool by_user) {
}
}
-void MessageCenter::DisableNotificationByExtension(
+void MessageCenter::OnDisableNotificationsByExtension(
const std::string& id) {
if (delegate_)
delegate_->DisableExtension(id);
@@ -158,23 +163,27 @@ void MessageCenter::DisableNotificationByExtension(
notification_list_->SendRemoveNotificationsByExtension(id);
}
-void MessageCenter::DisableNotificationByUrl(const std::string& id) {
+void MessageCenter::OnDisableNotificationsByUrl(const std::string& id) {
if (delegate_)
delegate_->DisableNotificationsFromSource(id);
notification_list_->SendRemoveNotificationsBySource(id);
}
-void MessageCenter::ShowNotificationSettings(const std::string& id) {
+void MessageCenter::OnShowNotificationSettings(const std::string& id) {
if (delegate_)
delegate_->ShowSettings(id);
}
-void MessageCenter::ShowNotificationSettingsDialog(gfx::NativeView context) {
+void MessageCenter::OnShowNotificationSettingsDialog(gfx::NativeView context) {
if (delegate_)
delegate_->ShowSettingsDialog(context);
}
-void MessageCenter::OnNotificationClicked(const std::string& id) {
+void MessageCenter::OnExpanded(const std::string& id) {
+ notification_list_->MarkNotificationAsExpanded(id);
+}
+
+void MessageCenter::OnClicked(const std::string& id) {
if (delegate_)
delegate_->OnClicked(id);
if (HasPopupNotifications()) {
@@ -183,10 +192,6 @@ void MessageCenter::OnNotificationClicked(const std::string& id) {
}
}
-void MessageCenter::OnQuietModeChanged(bool quiet_mode) {
- NotifyMessageCenterChanged(true);
-}
-
void MessageCenter::OnButtonClicked(const std::string& id, int button_index) {
if (delegate_)
delegate_->OnButtonClicked(id, button_index);
@@ -196,12 +201,17 @@ void MessageCenter::OnButtonClicked(const std::string& id, int button_index) {
}
}
-NotificationList* MessageCenter::GetNotificationList() {
- return notification_list_.get();
+//------------------------------------------------------------------------------
+// Overridden from NotificationList::Delegate:
+
+void MessageCenter::SendRemoveNotification(const std::string& id,
+ bool by_user) {
+ if (delegate_)
+ delegate_->NotificationRemoved(id, by_user);
}
-void MessageCenter::Delegate::OnButtonClicked(const std::string& id,
- int button_index) {
+void MessageCenter::OnQuietModeChanged(bool quiet_mode) {
+ NotifyMessageCenterChanged(true);
}
//------------------------------------------------------------------------------
diff --git a/ui/message_center/message_center.gyp b/ui/message_center/message_center.gyp
index 04847d1..46c8f8c 100644
--- a/ui/message_center/message_center.gyp
+++ b/ui/message_center/message_center.gyp
@@ -40,6 +40,7 @@
'message_center_util.h',
'notification.cc',
'notification.h',
+ 'notification_change_observer.h',
'notification_list.cc',
'notification_list.h',
'notification_types.cc',
diff --git a/ui/message_center/message_center.h b/ui/message_center/message_center.h
index a0c6e94..58575bd 100644
--- a/ui/message_center/message_center.h
+++ b/ui/message_center/message_center.h
@@ -11,6 +11,7 @@
#include "base/observer_list.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/message_center/message_center_export.h"
+#include "ui/message_center/notification_change_observer.h"
#include "ui/message_center/notification_list.h"
#include "ui/message_center/notification_types.h"
@@ -28,7 +29,8 @@ class DictionaryValue;
namespace message_center {
-class MESSAGE_CENTER_EXPORT MessageCenter : public NotificationList::Delegate {
+class MESSAGE_CENTER_EXPORT MessageCenter : public NotificationChangeObserver,
+ public NotificationList::Delegate {
public:
// Creates the global message center object.
static void Initialize();
@@ -51,6 +53,8 @@ class MESSAGE_CENTER_EXPORT MessageCenter : public NotificationList::Delegate {
class MESSAGE_CENTER_EXPORT Delegate {
public:
+ virtual ~Delegate();
+
// Called when the notification associated with |notification_id| is
// removed (i.e. closed by the user).
virtual void NotificationRemoved(const std::string& notification_id,
@@ -81,10 +85,7 @@ class MESSAGE_CENTER_EXPORT MessageCenter : public NotificationList::Delegate {
// TODO(miket): consider providing default implementations for the pure
// virtuals above, to avoid changing so many files in disparate parts of
// the codebase each time we enhance this interface.
- virtual void OnButtonClicked(const std::string& id, int button_index);
-
- protected:
- virtual ~Delegate() {}
+ virtual void OnButtonClicked(const std::string& id, int button_index) = 0;
};
// Called to set the delegate. Generally called only once, except in tests.
@@ -145,19 +146,25 @@ class MESSAGE_CENTER_EXPORT MessageCenter : public NotificationList::Delegate {
NotificationList* notification_list() { return notification_list_.get(); }
bool quiet_mode() const { return notification_list_->quiet_mode(); }
- // Overridden from NotificationList::Delegate.
+ // Overridden from NotificationChangeObserver:
+ virtual void OnRemoveNotification(const std::string& id, bool by_user)
+ OVERRIDE;
+ virtual void OnRemoveAllNotifications(bool by_user) OVERRIDE;
+ virtual void OnDisableNotificationsByExtension(const std::string& id)
+ OVERRIDE;
+ virtual void OnDisableNotificationsByUrl(const std::string& id) OVERRIDE;
+ virtual void OnShowNotificationSettings(const std::string& id) OVERRIDE;
+ virtual void OnShowNotificationSettingsDialog(gfx::NativeView context)
+ OVERRIDE;
+ virtual void OnExpanded(const std::string& id) OVERRIDE;
+ virtual void OnClicked(const std::string& id) OVERRIDE;
+ virtual void OnButtonClicked(const std::string& id, int button_index)
+ OVERRIDE;
+
+ // Overridden from NotificationList::Delegate:
virtual void SendRemoveNotification(const std::string& id,
bool by_user) OVERRIDE;
- virtual void SendRemoveAllNotifications(bool by_user) OVERRIDE;
- virtual void DisableNotificationByExtension(const std::string& id) OVERRIDE;
- virtual void DisableNotificationByUrl(const std::string& id) OVERRIDE;
- virtual void ShowNotificationSettings(const std::string& id) OVERRIDE;
- virtual void ShowNotificationSettingsDialog(gfx::NativeView context) OVERRIDE;
- virtual void OnNotificationClicked(const std::string& id) OVERRIDE;
virtual void OnQuietModeChanged(bool quiet_mode) OVERRIDE;
- virtual void OnButtonClicked(const std::string& id, int button_index)
- OVERRIDE;
- virtual NotificationList* GetNotificationList() OVERRIDE;
protected:
MessageCenter();
diff --git a/ui/message_center/message_center_tray.h b/ui/message_center/message_center_tray.h
index f40026f..9a3b33c0 100644
--- a/ui/message_center/message_center_tray.h
+++ b/ui/message_center/message_center_tray.h
@@ -60,7 +60,7 @@ class MESSAGE_CENTER_EXPORT MessageCenterTray
}
message_center::MessageCenter* message_center() { return message_center_; }
- // Overridden from message_center::MessageCenter::Observer.
+ // Overridden from message_center::MessageCenter::Observer:
virtual void OnMessageCenterChanged(bool new_notification) OVERRIDE;
// Overridden from SimpleMenuModel::Delegate.
diff --git a/ui/message_center/notification.cc b/ui/message_center/notification.cc
index 4bd1911..284d278 100644
--- a/ui/message_center/notification.cc
+++ b/ui/message_center/notification.cc
@@ -39,8 +39,9 @@ Notification::Notification(NotificationType type,
priority_(DEFAULT_PRIORITY),
timestamp_(base::Time::Now()),
serial_number_(g_next_serial_number_++),
+ shown_as_popup_(false),
is_read_(false),
- shown_as_popup_(false) {
+ is_expanded_(false) {
// This can override some data members initialized to deafule values above.
ApplyOptionalFields(optional_fields);
}
diff --git a/ui/message_center/notification.h b/ui/message_center/notification.h
index 2aed7d5..ffb301b 100644
--- a/ui/message_center/notification.h
+++ b/ui/message_center/notification.h
@@ -57,8 +57,8 @@ class MESSAGE_CENTER_EXPORT Notification {
// End unpacked values.
// Images fetched asynchronously.
- const gfx::Image& primary_icon() const { return primary_icon_; }
- void set_primary_icon(const gfx::Image& icon) { primary_icon_ = icon; }
+ const gfx::Image& icon() const { return icon_; }
+ void set_icon(const gfx::Image& icon) { icon_ = icon; }
const gfx::Image& image() const { return image_; }
void set_image(const gfx::Image& image) { image_ = image; }
@@ -67,15 +67,19 @@ class MESSAGE_CENTER_EXPORT Notification {
const std::vector<ButtonInfo>& buttons() const { return buttons_; }
bool SetButtonIcon(size_t index, const gfx::Image& icon);
- // Status in MessageCenter.
- bool is_read() const { return is_read_; }
- void set_is_read(bool is_read) { is_read_ = is_read; }
-
bool shown_as_popup() const { return shown_as_popup_; }
void set_shown_as_popup(bool shown_as_popup) {
shown_as_popup_ = shown_as_popup;
}
+ // Read status in the message center.
+ bool is_read() const { return is_read_; }
+ void set_is_read(bool read) { is_read_ = read; }
+
+ // Expanded status in the message center (not the popups).
+ bool is_expanded() const { return is_expanded_; }
+ void set_is_expanded(bool expanded) { is_expanded_ = expanded; }
+
// Used to keep the order of notifications with the same timestamp.
// The notification with lesser serial_number is considered 'older'.
unsigned serial_number() { return serial_number_; }
@@ -96,11 +100,12 @@ class MESSAGE_CENTER_EXPORT Notification {
unsigned serial_number_;
string16 expanded_message_;
std::vector<NotificationItem> items_;
- gfx::Image primary_icon_;
+ gfx::Image icon_;
gfx::Image image_;
std::vector<ButtonInfo> buttons_;
+ bool shown_as_popup_; // True if this has been shown as a popup.
bool is_read_; // True if this has been seen in the message center.
- bool shown_as_popup_; // True if this has been shown as a popup notification.
+ bool is_expanded_; // True if this has been expanded in the message center.
DISALLOW_COPY_AND_ASSIGN(Notification);
};
diff --git a/ui/message_center/notification_change_observer.h b/ui/message_center/notification_change_observer.h
new file mode 100644
index 0000000..ff45685
--- /dev/null
+++ b/ui/message_center/notification_change_observer.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_MESSAGE_CENTER_NOTIFICATION_CHANGE_OBSERVER_H_
+#define UI_MESSAGE_CENTER_NOTIFICATION_CHANGE_OBSERVER_H_
+
+#include <string>
+
+#include "ui/gfx/native_widget_types.h"
+
+namespace message_center {
+
+// For classes that need to handle or propagate notification changes.
+class MESSAGE_CENTER_EXPORT NotificationChangeObserver {
+ public:
+ virtual ~NotificationChangeObserver() {};
+
+ virtual void OnRemoveNotification(const std::string& id, bool by_user) {};
+ virtual void OnRemoveAllNotifications(bool by_user) {};
+
+ virtual void OnDisableNotificationsByExtension(const std::string& id) {};
+ virtual void OnDisableNotificationsByUrl(const std::string& id) {};
+
+ virtual void OnShowNotificationSettings(const std::string& id) {};
+ virtual void OnShowNotificationSettingsDialog(gfx::NativeView context) {};
+
+ virtual void OnExpanded(const std::string& id) {};
+ virtual void OnClicked(const std::string& id) {};
+ virtual void OnButtonClicked(const std::string& id, int button_index) {};
+};
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_NOTIFICATION_CHANGE_OBSERVER_H_
diff --git a/ui/message_center/notification_list.cc b/ui/message_center/notification_list.cc
index 4f0c69a..2e108f9 100644
--- a/ui/message_center/notification_list.cc
+++ b/ui/message_center/notification_list.cc
@@ -38,6 +38,9 @@ bool CompareTimestampSerial::operator()(Notification* n1, Notification* n2) {
const size_t NotificationList::kMaxVisibleMessageCenterNotifications = 100;
const size_t NotificationList::kMaxVisiblePopupNotifications = 2;
+NotificationList::Delegate::~Delegate() {
+}
+
NotificationList::NotificationList(Delegate* delegate)
: delegate_(delegate),
message_center_visible_(false),
@@ -157,7 +160,7 @@ bool NotificationList::SetNotificationIcon(const std::string& notification_id,
Notifications::iterator iter = GetNotification(notification_id);
if (iter == notifications_.end())
return false;
- (*iter)->set_primary_icon(image);
+ (*iter)->set_icon(image);
return true;
}
@@ -247,6 +250,12 @@ void NotificationList::MarkSinglePopupAsShown(
}
}
+void NotificationList::MarkNotificationAsExpanded(const std::string& id) {
+ Notifications::iterator iter = GetNotification(id);
+ if (iter != notifications_.end())
+ (*iter)->set_is_expanded(true);
+}
+
void NotificationList::SetQuietMode(bool quiet_mode) {
SetQuietModeInternal(quiet_mode);
quiet_mode_timer_.reset();
diff --git a/ui/message_center/notification_list.h b/ui/message_center/notification_list.h
index be8718c..9a4c957 100644
--- a/ui/message_center/notification_list.h
+++ b/ui/message_center/notification_list.h
@@ -45,37 +45,14 @@ class MESSAGE_CENTER_EXPORT NotificationList {
class MESSAGE_CENTER_EXPORT Delegate {
public:
- Delegate() {}
- virtual ~Delegate() {}
+ virtual ~Delegate();
// Removes notifications
virtual void SendRemoveNotification(const std::string& id,
bool by_user) = 0;
- virtual void SendRemoveAllNotifications(bool by_user) = 0;
-
- // Disables notifications
- virtual void DisableNotificationByExtension(const std::string& id) = 0;
- virtual void DisableNotificationByUrl(const std::string& id) = 0;
-
- // Requests the Delegate to show the settings page.
- virtual void ShowNotificationSettings(const std::string& id) = 0;
-
- // Requests the Delegate to show the settings dialog.
- virtual void ShowNotificationSettingsDialog(gfx::NativeView context) = 0;
-
- // Called when a notification is clicked on.
- virtual void OnNotificationClicked(const std::string& id) = 0;
// Called when the quiet mode status has been changed.
virtual void OnQuietModeChanged(bool quiet_mode) = 0;
-
- // Called when a button in a notification is clicked. |button_index|
- // indicates which button was clicked, zero-indexed (button one is 0,
- // button two is 1).
- virtual void OnButtonClicked(const std::string& id, int button_index) = 0;
-
- // Returns the list of notifications to display.
- virtual NotificationList* GetNotificationList() = 0;
};
explicit NotificationList(Delegate* delegate);
@@ -139,6 +116,9 @@ class MESSAGE_CENTER_EXPORT NotificationList {
void MarkSinglePopupAsShown(const std::string& id,
bool mark_notification_as_read);
+ // Marks the specified notification as expanded in the notification center.
+ void MarkNotificationAsExpanded(const std::string& id);
+
bool quiet_mode() const { return quiet_mode_; }
// Sets the current quiet mode status to |quiet_mode|. The new status is not
diff --git a/ui/message_center/notification_list_unittest.cc b/ui/message_center/notification_list_unittest.cc
index 4cf791e..aa4ab66 100644
--- a/ui/message_center/notification_list_unittest.cc
+++ b/ui/message_center/notification_list_unittest.cc
@@ -27,42 +27,15 @@ class MockNotificationListDelegate : public NotificationList::Delegate {
}
private:
- // NotificationList::Delegate overrides:
+ // Overridden from NotificationList::Delegate:
virtual void SendRemoveNotification(const std::string& id,
bool by_user) OVERRIDE {
send_remove_count_++;
}
- virtual void SendRemoveAllNotifications(bool by_user) OVERRIDE {
- }
-
- virtual void DisableNotificationByExtension(const std::string& id) OVERRIDE {
- }
-
- virtual void DisableNotificationByUrl(const std::string& id) OVERRIDE {
- }
-
- virtual void ShowNotificationSettings(const std::string& id) OVERRIDE {
- }
-
- virtual void ShowNotificationSettingsDialog(
- gfx::NativeView context) OVERRIDE {
- }
-
- virtual void OnNotificationClicked(const std::string& id) OVERRIDE {
- }
-
virtual void OnQuietModeChanged(bool quiet_mode) OVERRIDE {
}
- virtual void OnButtonClicked(const std::string& id,
- int button_index) OVERRIDE {
- }
-
- virtual NotificationList* GetNotificationList() OVERRIDE {
- return NULL;
- }
-
size_t send_remove_count_;
DISALLOW_COPY_AND_ASSIGN(MockNotificationListDelegate);
};
diff --git a/ui/message_center/views/message_bubble_base.cc b/ui/message_center/views/message_bubble_base.cc
index d7fc5e7..7438496 100644
--- a/ui/message_center/views/message_bubble_base.cc
+++ b/ui/message_center/views/message_bubble_base.cc
@@ -26,8 +26,8 @@ const SkColor MessageBubbleBase::kHeaderBackgroundColorLight =
const SkColor MessageBubbleBase::kHeaderBackgroundColorDark =
SkColorSetRGB(0xe7, 0xe7, 0xe7);
-MessageBubbleBase::MessageBubbleBase(NotificationList::Delegate* list_delegate)
- : list_delegate_(list_delegate),
+MessageBubbleBase::MessageBubbleBase(MessageCenter* message_center)
+ : message_center_(message_center),
bubble_view_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
max_height_(kMessageBubbleBaseDefaultMaxHeight) {
diff --git a/ui/message_center/views/message_bubble_base.h b/ui/message_center/views/message_bubble_base.h
index f43c9b7..c7255f8 100644
--- a/ui/message_center/views/message_bubble_base.h
+++ b/ui/message_center/views/message_bubble_base.h
@@ -6,15 +6,15 @@
#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_BUBBLE_BASE_H_
#include "base/memory/scoped_ptr.h"
+#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_export.h"
-#include "ui/message_center/notification_list.h"
#include "ui/views/bubble/tray_bubble_view.h"
namespace message_center {
class MESSAGE_CENTER_EXPORT MessageBubbleBase {
public:
- explicit MessageBubbleBase(NotificationList::Delegate* list_delegate);
+ explicit MessageBubbleBase(MessageCenter* message_center);
virtual ~MessageBubbleBase();
@@ -61,13 +61,13 @@ class MESSAGE_CENTER_EXPORT MessageBubbleBase {
protected:
views::TrayBubbleView::InitParams GetDefaultInitParams(
views::TrayBubbleView::AnchorAlignment anchor_alignment);
- NotificationList::Delegate* list_delegate() { return list_delegate_; }
+ MessageCenter* message_center() { return message_center_; }
void set_bubble_view(views::TrayBubbleView* bubble_view) {
bubble_view_ = bubble_view;
}
private:
- NotificationList::Delegate* list_delegate_;
+ MessageCenter* message_center_;
views::TrayBubbleView* bubble_view_;
base::WeakPtrFactory<MessageBubbleBase> weak_ptr_factory_;
int max_height_;
diff --git a/ui/message_center/views/message_center_bubble.cc b/ui/message_center/views/message_center_bubble.cc
index a64c854..b91854e 100644
--- a/ui/message_center/views/message_center_bubble.cc
+++ b/ui/message_center/views/message_center_bubble.cc
@@ -4,6 +4,8 @@
#include "ui/message_center/views/message_center_bubble.h"
+#include <map>
+
#include "grit/ui_strings.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "ui/base/l10n/l10n_util.h"
@@ -49,8 +51,8 @@ const SkColor kFocusBorderColor = SkColorSetRGB(0x40, 0x80, 0xfa);
class WebNotificationButtonViewBase : public views::View {
public:
- WebNotificationButtonViewBase(NotificationList::Delegate* list_delegate)
- : list_delegate_(list_delegate),
+ WebNotificationButtonViewBase(NotificationChangeObserver* observer)
+ : observer_(observer),
close_all_button_(NULL) {}
void SetCloseAllVisible(bool visible) {
@@ -63,11 +65,11 @@ class WebNotificationButtonViewBase : public views::View {
}
protected:
- NotificationList::Delegate* list_delegate() { return list_delegate_; }
+ NotificationChangeObserver* observer() { return observer_; }
views::Button* close_all_button() { return close_all_button_; }
private:
- NotificationList::Delegate* list_delegate_;
+ NotificationChangeObserver* observer_; // Weak reference.
views::Button* close_all_button_;
DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonViewBase);
@@ -77,8 +79,8 @@ class WebNotificationButtonViewBase : public views::View {
class WebNotificationButtonView : public WebNotificationButtonViewBase,
public views::ButtonListener {
public:
- explicit WebNotificationButtonView(NotificationList::Delegate* list_delegate)
- : WebNotificationButtonViewBase(list_delegate) {
+ explicit WebNotificationButtonView(NotificationChangeObserver* observer)
+ : WebNotificationButtonViewBase(observer) {
set_background(views::Background::CreateBackgroundPainter(
true,
views::Painter::CreateVerticalGradient(
@@ -111,11 +113,11 @@ class WebNotificationButtonView : public WebNotificationButtonViewBase,
virtual ~WebNotificationButtonView() {}
- // Overridden from ButtonListener.
+ // Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE {
if (sender == close_all_button())
- list_delegate()->SendRemoveAllNotifications(true); // Action by user.
+ observer()->OnRemoveAllNotifications(true); // Action by user.
}
private:
@@ -134,7 +136,7 @@ class WebNotificationButton : public views::TextButton {
}
protected:
- // views::View overrides:
+ // Overridden from views::View:
virtual gfx::Size GetPreferredSize() OVERRIDE {
// Returns an empty size when invisible, to trim its space in the parent's
// GridLayout.
@@ -164,8 +166,8 @@ class WebNotificationButton : public views::TextButton {
class WebNotificationButtonView2 : public WebNotificationButtonViewBase,
public views::ButtonListener {
public:
- explicit WebNotificationButtonView2(NotificationList::Delegate* list_delegate)
- : WebNotificationButtonViewBase(list_delegate) {
+ explicit WebNotificationButtonView2(NotificationChangeObserver* observer)
+ : WebNotificationButtonViewBase(observer) {
set_background(views::Background::CreateSolidBackground(
kMessageCenterBackgroundColor));
set_border(views::Border::CreateSolidSidedBorder(
@@ -206,13 +208,13 @@ class WebNotificationButtonView2 : public WebNotificationButtonViewBase,
}
private:
- // views::ButtonListener overrides:
+ // Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE {
if (sender == close_all_button())
- list_delegate()->SendRemoveAllNotifications(true); // Action by user.
+ observer()->OnRemoveAllNotifications(true); // Action by user.
else if (sender == settings_button_)
- list_delegate()->ShowNotificationSettingsDialog(
+ observer()->OnShowNotificationSettingsDialog(
GetWidget()->GetNativeView());
else
NOTREACHED();
@@ -224,10 +226,13 @@ class WebNotificationButtonView2 : public WebNotificationButtonViewBase,
DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonView2);
};
-// A custom scroll-view that has a specified size.
-class FixedSizedScrollView : public views::ScrollView {
+// A custom scroll view whose height has a minimum and maximum value and whose
+// scroll bar disappears when not needed.
+class BoundedScrollView : public views::ScrollView {
public:
- FixedSizedScrollView() {
+ BoundedScrollView(int min_height, int max_height)
+ : min_height_(min_height),
+ max_height_(max_height) {
set_notify_enter_exit_on_child(true);
if (IsRichNotificationEnabled()) {
set_background(views::Background::CreateSolidBackground(
@@ -235,53 +240,51 @@ class FixedSizedScrollView : public views::ScrollView {
}
}
- virtual ~FixedSizedScrollView() {}
-
- void SetFixedSize(const gfx::Size& size) {
- if (fixed_size_ == size)
- return;
- fixed_size_ = size;
- PreferredSizeChanged();
- }
+ virtual ~BoundedScrollView() {}
- // views::View overrides.
+ // Overridden from views::View:
virtual gfx::Size GetPreferredSize() OVERRIDE {
- gfx::Size size = fixed_size_.IsEmpty() ?
- contents()->GetPreferredSize() : fixed_size_;
+ gfx::Size size = contents()->GetPreferredSize();
+ size.ClampToMin(gfx::Size(size.width(), min_height_));
+ size.ClampToMax(gfx::Size(size.width(), max_height_));
gfx::Insets insets = GetInsets();
size.Enlarge(insets.width(), insets.height());
return size;
}
virtual void Layout() OVERRIDE {
- gfx::Rect bounds = gfx::Rect(contents()->GetPreferredSize());
- bounds.set_width(std::max(0, width() - GetScrollBarWidth()));
- contents()->SetBoundsRect(bounds);
-
+ // Lay out the view as if it will have a scroll bar.
+ gfx::Rect content_bounds = gfx::Rect(contents()->GetPreferredSize());
+ content_bounds.set_width(std::max(0, width() - GetScrollBarWidth()));
+ contents()->SetBoundsRect(content_bounds);
views::ScrollView::Layout();
+
+ // But use the scroll bar space if no scroll bar is needed.
if (!vertical_scroll_bar()->visible()) {
- gfx::Rect bounds = contents()->bounds();
- bounds.set_width(bounds.width() + GetScrollBarWidth());
- contents()->SetBoundsRect(bounds);
+ content_bounds = contents()->bounds();
+ content_bounds.set_width(content_bounds.width() + GetScrollBarWidth());
+ contents()->SetBoundsRect(content_bounds);
}
}
virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE {
- gfx::Rect bounds = gfx::Rect(contents()->GetPreferredSize());
- bounds.set_width(std::max(0, width() - GetScrollBarWidth()));
- contents()->SetBoundsRect(bounds);
+ // Make sure any content resizing takes into account the scroll bar.
+ gfx::Rect content_bounds = gfx::Rect(contents()->GetPreferredSize());
+ content_bounds.set_width(std::max(0, width() - GetScrollBarWidth()));
+ contents()->SetBoundsRect(content_bounds);
}
private:
- gfx::Size fixed_size_;
+ int min_height_;
+ int max_height_;
- DISALLOW_COPY_AND_ASSIGN(FixedSizedScrollView);
+ DISALLOW_COPY_AND_ASSIGN(BoundedScrollView);
};
-// Container for the messages.
-class ScrollContentView : public views::View {
+// Displays a list of messages.
+class MessageListView : public views::View {
public:
- ScrollContentView() {
+ MessageListView() {
if (IsRichNotificationEnabled()) {
// Set the margin to 0 for the layout. BoxLayout assumes the same margin
// for top and bottom, but the bottom margin here should be smaller
@@ -308,39 +311,33 @@ class ScrollContentView : public views::View {
}
}
- virtual ~ScrollContentView() {
- }
-
- virtual gfx::Size GetPreferredSize() OVERRIDE {
- if (!preferred_size_.IsEmpty())
- return preferred_size_;
- return views::View::GetPreferredSize();
+ virtual ~MessageListView() {
}
- void set_preferred_size(const gfx::Size& size) { preferred_size_ = size; }
-
private:
- gfx::Size preferred_size_;
- DISALLOW_COPY_AND_ASSIGN(ScrollContentView);
+ DISALLOW_COPY_AND_ASSIGN(MessageListView);
};
} // namespace
-// Message Center contents.
-class MessageCenterContentsView : public views::View {
+// View that displays the whole message center.
+class MessageCenterView : public views::View {
public:
- explicit MessageCenterContentsView(MessageCenterBubble* bubble,
- NotificationList::Delegate* list_delegate)
- : list_delegate_(list_delegate),
- bubble_(bubble) {
+ MessageCenterView(MessageCenterBubble* bubble) : bubble_(bubble) {
int between_child = IsRichNotificationEnabled() ? 0 : 1;
SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, between_child));
- scroll_content_ = new ScrollContentView;
- scroller_ = new FixedSizedScrollView;
- scroller_->SetContents(scroll_content_);
- AddChildView(scroller_);
+
+ if (IsRichNotificationEnabled())
+ button_view_ = new WebNotificationButtonView2(bubble_);
+ else
+ button_view_ = new WebNotificationButtonView(bubble_);
+
+ const int button_height = button_view_->GetPreferredSize().height();
+ const int min_height = kMessageBubbleBaseMinHeight - button_height;
+ const int max_height = bubble_->max_height() - button_height;
+ scroller_ = new BoundedScrollView(min_height, max_height);
if (get_use_acceleration_when_possible()) {
scroller_->SetPaintToLayer(true);
@@ -348,31 +345,28 @@ class MessageCenterContentsView : public views::View {
scroller_->layer()->SetMasksToBounds(true);
}
- if (IsRichNotificationEnabled())
- button_view_ = new WebNotificationButtonView2(list_delegate);
- else
- button_view_ = new WebNotificationButtonView(list_delegate);
+ message_list_view_ = new MessageListView();
+ scroller_->SetContents(message_list_view_);
+
+ AddChildView(scroller_);
AddChildView(button_view_);
}
void FocusContents() {
}
- void Update(const NotificationList::Notifications& notifications) {
- scroll_content_->RemoveAllChildViews(true);
- scroll_content_->set_preferred_size(gfx::Size());
- size_t num_children = 0;
+ void UpdateAllNotifications(
+ const NotificationList::Notifications& notifications) {
+ RemoveAllNotifications();
for (NotificationList::Notifications::const_iterator iter =
notifications.begin(); iter != notifications.end(); ++iter) {
- MessageView* view = NotificationView::Create(*(*iter), list_delegate_);
- view->set_scroller(scroller_);
- scroll_content_->AddChildView(view);
- if (++num_children >=
+ AddNotification(*(*iter));
+ if (message_views_.size() >=
NotificationList::kMaxVisibleMessageCenterNotifications) {
break;
}
}
- if (num_children == 0) {
+ if (message_views_.empty()) {
views::Label* label = new views::Label(l10n_util::GetStringUTF16(
IDS_MESSAGE_CENTER_NO_MESSAGES));
label->SetFont(label->font().DeriveFont(1));
@@ -380,53 +374,70 @@ class MessageCenterContentsView : public views::View {
// Set transparent background to ensure that subpixel rendering
// is disabled. See crbug.com/169056
label->SetBackgroundColor(kTransparentColor);
- scroll_content_->AddChildView(label);
+ message_list_view_->AddChildView(label);
button_view_->SetCloseAllVisible(false);
scroller_->set_focusable(false);
} else {
button_view_->SetCloseAllVisible(true);
scroller_->set_focusable(true);
}
- SizeScrollContent();
Layout();
- if (GetWidget())
- GetWidget()->GetRootView()->SchedulePaint();
+ }
+
+ void UpdateOneNotification(const Notification& notification) {
+ // Update the corresponding message view if there is one and explicitly
+ // update this view's layout as this is not automatic in spite of the
+ // updated view's likely size change because ScrollView's Viewport breaks
+ // the ChildPreferredSizeChange() chain.
+ MessageView* view = message_views_[notification.id()];
+ if (view) {
+ view->Update(notification);
+ Layout();
+ }
}
size_t NumMessageViews() const {
- return scroll_content_->child_count();
+ return message_list_view_->child_count();
+ }
+
+ protected:
+ // Overridden from views::View:
+ virtual void Layout() OVERRIDE {
+ scroller_->SizeToPreferredSize();
+ views::View::Layout();
+ if (GetWidget())
+ GetWidget()->GetRootView()->SchedulePaint();
+ bubble_->bubble_view()->UpdateBubble();
}
private:
- void SizeScrollContent() {
- gfx::Size scroll_size = scroll_content_->GetPreferredSize();
- const int button_height = button_view_->GetPreferredSize().height();
- const int min_height = kMessageBubbleBaseMinHeight - button_height;
- const int max_height = bubble_->max_height() - button_height;
- int scroll_height = std::min(std::max(
- scroll_size.height(), min_height), max_height);
- scroll_size.set_height(scroll_height);
- if (scroll_height == min_height)
- scroll_content_->set_preferred_size(scroll_size);
- else
- scroll_content_->set_preferred_size(gfx::Size());
- scroller_->SetFixedSize(scroll_size);
- scroller_->SizeToPreferredSize();
- scroll_content_->InvalidateLayout();
+
+ void RemoveAllNotifications() {
+ message_views_.clear();
+ message_list_view_->RemoveAllChildViews(true);
+ }
+
+ void AddNotification(const Notification& notification) {
+ // Always expand the first (topmost) notification.
+ bool expand = (notification.is_expanded() || message_views_.empty());
+ MessageView* view = NotificationView::Create(notification, bubble_, expand);
+ view->set_scroller(scroller_);
+ message_views_[notification.id()] = view;
+ message_list_view_->AddChildView(view);
}
- NotificationList::Delegate* list_delegate_;
- FixedSizedScrollView* scroller_;
- ScrollContentView* scroll_content_;
+ MessageCenterBubble* bubble_; // Weak reference.
+ std::map<std::string,MessageView*> message_views_;
+ BoundedScrollView* scroller_;
+ MessageListView* message_list_view_;
WebNotificationButtonViewBase* button_view_;
- MessageCenterBubble* bubble_;
- DISALLOW_COPY_AND_ASSIGN(MessageCenterContentsView);
+ DISALLOW_COPY_AND_ASSIGN(MessageCenterView);
};
// Message Center Bubble.
-MessageCenterBubble::MessageCenterBubble(NotificationList::Delegate* delegate)
- : MessageBubbleBase(delegate),
+MessageCenterBubble::MessageCenterBubble(MessageCenter* message_center)
+ : MessageBubbleBase(message_center),
contents_view_(NULL) {
}
@@ -448,7 +459,7 @@ views::TrayBubbleView::InitParams MessageCenterBubble::GetInitParams(
void MessageCenterBubble::InitializeContents(
views::TrayBubbleView* new_bubble_view) {
set_bubble_view(new_bubble_view);
- contents_view_ = new MessageCenterContentsView(this, list_delegate());
+ contents_view_ = new MessageCenterView(this);
bubble_view()->AddChildView(contents_view_);
// Resize the content of the bubble view to the given bubble size. This is
// necessary in case of the bubble border forcing a bigger size then the
@@ -466,8 +477,8 @@ void MessageCenterBubble::UpdateBubbleView() {
if (!bubble_view())
return; // Could get called after view is closed
const NotificationList::Notifications& notifications =
- list_delegate()->GetNotificationList()->GetNotifications();
- contents_view_->Update(notifications);
+ message_center()->notification_list()->GetNotifications();
+ contents_view_->UpdateAllNotifications(notifications);
bubble_view()->Show();
bubble_view()->UpdateBubble();
}
@@ -478,6 +489,57 @@ void MessageCenterBubble::OnMouseEnteredView() {
void MessageCenterBubble::OnMouseExitedView() {
}
+void MessageCenterBubble::OnRemoveNotification(const std::string& id,
+ bool by_user) {
+ message_center()->OnRemoveNotification(id, by_user);
+}
+
+void MessageCenterBubble::OnRemoveAllNotifications(bool by_user) {
+ message_center()->OnRemoveAllNotifications(by_user);
+}
+
+void MessageCenterBubble::OnDisableNotificationsByExtension(
+ const std::string& id) {
+ message_center()->OnDisableNotificationsByExtension(id);
+}
+
+void MessageCenterBubble::OnDisableNotificationsByUrl(const std::string& id) {
+ message_center()->OnDisableNotificationsByUrl(id);
+}
+
+void MessageCenterBubble::OnShowNotificationSettings(const std::string& id) {
+ message_center()->OnShowNotificationSettings(id);
+}
+
+void MessageCenterBubble::OnShowNotificationSettingsDialog(
+ gfx::NativeView context) {
+ message_center()->OnShowNotificationSettingsDialog(context);
+}
+
+void MessageCenterBubble::OnClicked(const std::string& id) {
+ message_center()->OnClicked(id);
+}
+
+void MessageCenterBubble::OnButtonClicked(const std::string& id,
+ int button_index) {
+ message_center()->OnButtonClicked(id, button_index);
+}
+
+void MessageCenterBubble::OnExpanded(const std::string& id) {
+ message_center()->OnExpanded(id);
+
+ // Update the view corresponding to this notification.
+ const NotificationList::Notifications& notifications =
+ message_center()->notification_list()->GetNotifications();
+ for (NotificationList::Notifications::const_iterator iter =
+ notifications.begin(); iter != notifications.end(); ++iter) {
+ if ((*iter)->id() == id) {
+ contents_view_->UpdateOneNotification(*(*iter));
+ break;
+ }
+ }
+}
+
size_t MessageCenterBubble::NumMessageViewsForTest() const {
return contents_view_->NumMessageViews();
}
diff --git a/ui/message_center/views/message_center_bubble.h b/ui/message_center/views/message_center_bubble.h
index 3b77571..bed2262 100644
--- a/ui/message_center/views/message_center_bubble.h
+++ b/ui/message_center/views/message_center_bubble.h
@@ -6,21 +6,23 @@
#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_BUBBLE_H_
#include "ui/message_center/message_center_export.h"
-#include "ui/message_center/notification_list.h"
+#include "ui/message_center/notification_change_observer.h"
#include "ui/message_center/views/message_bubble_base.h"
namespace message_center {
-class MessageCenterContentsView;
+class MessageCenterView;
// Bubble for message center.
-class MESSAGE_CENTER_EXPORT MessageCenterBubble : public MessageBubbleBase {
+class MESSAGE_CENTER_EXPORT MessageCenterBubble
+ : public MessageBubbleBase,
+ public NotificationChangeObserver {
public:
- explicit MessageCenterBubble(NotificationList::Delegate* delegate);
+ explicit MessageCenterBubble(MessageCenter* message_center);
virtual ~MessageCenterBubble();
- // Overridden from MessageBubbleBase.
+ // Overridden from MessageBubbleBase:
virtual views::TrayBubbleView::InitParams GetInitParams(
views::TrayBubbleView::AnchorAlignment anchor_alignment) OVERRIDE;
virtual void InitializeContents(views::TrayBubbleView* bubble_view) OVERRIDE;
@@ -29,10 +31,25 @@ class MESSAGE_CENTER_EXPORT MessageCenterBubble : public MessageBubbleBase {
virtual void OnMouseEnteredView() OVERRIDE;
virtual void OnMouseExitedView() OVERRIDE;
+ // Overridden from NotificationChangeObserver:
+ virtual void OnRemoveNotification(const std::string& id, bool by_user)
+ OVERRIDE;
+ virtual void OnRemoveAllNotifications(bool by_user) OVERRIDE;
+ virtual void OnDisableNotificationsByExtension(const std::string& id)
+ OVERRIDE;
+ virtual void OnDisableNotificationsByUrl(const std::string& id) OVERRIDE;
+ virtual void OnShowNotificationSettings(const std::string& id) OVERRIDE;
+ virtual void OnShowNotificationSettingsDialog(gfx::NativeView context)
+ OVERRIDE;
+ virtual void OnExpanded(const std::string& id) OVERRIDE;
+ virtual void OnClicked(const std::string& id) OVERRIDE;
+ virtual void OnButtonClicked(const std::string& id,
+ int button_index) OVERRIDE;
+
size_t NumMessageViewsForTest() const;
private:
- MessageCenterContentsView* contents_view_;
+ MessageCenterView* contents_view_;
// The maximum height
int max_height_;
diff --git a/ui/message_center/views/message_popup_bubble.cc b/ui/message_center/views/message_popup_bubble.cc
index 696b016..46238dd 100644
--- a/ui/message_center/views/message_popup_bubble.cc
+++ b/ui/message_center/views/message_popup_bubble.cc
@@ -8,6 +8,7 @@
#include "base/stl_util.h"
#include "ui/message_center/message_center_constants.h"
#include "ui/message_center/notification.h"
+#include "ui/message_center/notification_change_observer.h"
#include "ui/message_center/notification_types.h"
#include "ui/message_center/views/message_view.h"
#include "ui/message_center/views/notification_view.h"
@@ -21,7 +22,7 @@ namespace message_center {
// Popup notifications contents.
class PopupBubbleContentsView : public views::View {
public:
- explicit PopupBubbleContentsView(NotificationList::Delegate* list_delegate);
+ explicit PopupBubbleContentsView(NotificationChangeObserver* observer);
void Update(const NotificationList::PopupNotifications& popup_notifications);
@@ -30,15 +31,15 @@ class PopupBubbleContentsView : public views::View {
}
private:
- NotificationList::Delegate* list_delegate_;
+ NotificationChangeObserver* observer_; // Weak reference.
views::View* content_;
DISALLOW_COPY_AND_ASSIGN(PopupBubbleContentsView);
};
PopupBubbleContentsView::PopupBubbleContentsView(
- NotificationList::Delegate* list_delegate)
- : list_delegate_(list_delegate) {
+ NotificationChangeObserver* observer)
+ : observer_(observer) {
SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
content_ = new views::View;
@@ -59,7 +60,11 @@ void PopupBubbleContentsView::Update(
for (NotificationList::PopupNotifications::const_iterator iter =
popup_notifications.begin();
iter != popup_notifications.end(); ++iter) {
- content_->AddChildView(NotificationView::Create(*(*iter), list_delegate_));
+ // NotificationViews are expanded by default here because MessagePopupBubble
+ // hasn't been tested yet with changing subview sizes, and such changes
+ // could come if those subviews were initially collapsed and allowed to be
+ // expanded by users. TODO(dharcourt): Fix.
+ content_->AddChildView(NotificationView::Create(*(*iter), observer_, true));
}
content_->SizeToPreferredSize();
content_->InvalidateLayout();
@@ -113,8 +118,8 @@ void MessagePopupBubble::AutocloseTimer::Suspend() {
}
// MessagePopupBubble
-MessagePopupBubble::MessagePopupBubble(NotificationList::Delegate* delegate)
- : MessageBubbleBase(delegate),
+MessagePopupBubble::MessagePopupBubble(MessageCenter* message_center)
+ : MessageBubbleBase(message_center),
contents_view_(NULL) {
}
@@ -135,7 +140,7 @@ views::TrayBubbleView::InitParams MessagePopupBubble::GetInitParams(
void MessagePopupBubble::InitializeContents(
views::TrayBubbleView* new_bubble_view) {
set_bubble_view(new_bubble_view);
- contents_view_ = new PopupBubbleContentsView(list_delegate());
+ contents_view_ = new PopupBubbleContentsView(message_center());
bubble_view()->AddChildView(contents_view_);
UpdateBubbleView();
}
@@ -146,7 +151,7 @@ void MessagePopupBubble::OnBubbleViewDestroyed() {
void MessagePopupBubble::UpdateBubbleView() {
NotificationList::PopupNotifications popups =
- list_delegate()->GetNotificationList()->GetPopupNotifications();
+ message_center()->notification_list()->GetPopupNotifications();
if (popups.size() == 0) {
if (bubble_view())
@@ -200,7 +205,7 @@ void MessagePopupBubble::OnMouseExitedView() {
void MessagePopupBubble::OnAutoClose(const std::string& id) {
DeleteTimer(id);
- list_delegate()->GetNotificationList()->MarkSinglePopupAsShown(id, false);
+ message_center()->notification_list()->MarkSinglePopupAsShown(id, false);
UpdateBubbleView();
}
diff --git a/ui/message_center/views/message_popup_bubble.h b/ui/message_center/views/message_popup_bubble.h
index 060d22f..671c0b6 100644
--- a/ui/message_center/views/message_popup_bubble.h
+++ b/ui/message_center/views/message_popup_bubble.h
@@ -11,7 +11,6 @@
#include "base/timer.h"
#include "ui/message_center/message_center_export.h"
-#include "ui/message_center/notification_list.h"
#include "ui/message_center/views/message_bubble_base.h"
namespace message_center {
@@ -21,11 +20,11 @@ class PopupBubbleContentsView;
// Bubble for popup notifications.
class MESSAGE_CENTER_EXPORT MessagePopupBubble : public MessageBubbleBase {
public:
- explicit MessagePopupBubble(NotificationList::Delegate* delegate);
+ explicit MessagePopupBubble(MessageCenter* message_center);
virtual ~MessagePopupBubble();
- // Overridden from MessageBubbleBase.
+ // Overridden from MessageBubbleBase:
virtual views::TrayBubbleView::InitParams GetInitParams(
views::TrayBubbleView::AnchorAlignment anchor_alignment) OVERRIDE;
virtual void InitializeContents(views::TrayBubbleView* bubble_view) OVERRIDE;
diff --git a/ui/message_center/views/message_popup_collection.cc b/ui/message_center/views/message_popup_collection.cc
index f00308d..fb81d69 100644
--- a/ui/message_center/views/message_popup_collection.cc
+++ b/ui/message_center/views/message_popup_collection.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/timer.h"
#include "ui/gfx/screen.h"
+#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_constants.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_list.h"
@@ -18,6 +19,7 @@
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_delegate.h"
namespace message_center {
@@ -85,7 +87,7 @@ class ToastContentsView : public views::WidgetDelegateView {
base::Unretained(GetWidget())));
}
- // views::WidgetDelegate overrides:
+ // Overridden from views::WidgetDelegate:
virtual views::View* GetContentsView() OVERRIDE {
return this;
}
@@ -99,7 +101,7 @@ class ToastContentsView : public views::WidgetDelegateView {
return false;
}
- // views::View overrides:
+ // Overridden from views::View:
virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE {
collection_->OnMouseEntered();
}
@@ -117,12 +119,11 @@ class ToastContentsView : public views::WidgetDelegateView {
DISALLOW_COPY_AND_ASSIGN(ToastContentsView);
};
-MessagePopupCollection::MessagePopupCollection(
- gfx::NativeView context,
- NotificationList::Delegate* list_delegate)
+MessagePopupCollection::MessagePopupCollection(gfx::NativeView context,
+ MessageCenter* message_center)
: context_(context),
- list_delegate_(list_delegate) {
- DCHECK(list_delegate_);
+ message_center_(message_center) {
+ DCHECK(message_center_);
}
MessagePopupCollection::~MessagePopupCollection() {
@@ -131,7 +132,7 @@ MessagePopupCollection::~MessagePopupCollection() {
void MessagePopupCollection::UpdatePopups() {
NotificationList::PopupNotifications popups =
- list_delegate_->GetNotificationList()->GetPopupNotifications();
+ message_center_->notification_list()->GetPopupNotifications();
if (popups.empty()) {
CloseAllWidgets();
@@ -153,7 +154,12 @@ void MessagePopupCollection::UpdatePopups() {
popups.begin(); iter != popups.end(); ++iter) {
ToastContainer::iterator toast_iter = toasts_.find((*iter)->id());
views::Widget* widget = NULL;
- MessageView* view = NotificationView::Create(*(*iter), list_delegate_);
+ // NotificationViews are expanded by default here because
+ // MessagePopupCollection hasn't been tested yet with changing subview
+ // sizes, and such changes could come if those subviews were initially
+ // collapsed and allowed to be expanded by users. TODO(dharcourt): Fix.
+ MessageView* view = NotificationView::Create(*(*iter), message_center_,
+ true);
if (toast_iter != toasts_.end()) {
widget = toast_iter->second->GetWidget();
old_toast_ids.erase((*iter)->id());
@@ -240,7 +246,7 @@ void MessagePopupCollection::OnWidgetDestroying(views::Widget* widget) {
for (ToastContainer::iterator iter = toasts_.begin();
iter != toasts_.end(); ++iter) {
if (iter->second->GetWidget() == widget) {
- list_delegate_->GetNotificationList()->MarkSinglePopupAsShown(
+ message_center_->notification_list()->MarkSinglePopupAsShown(
iter->first, false);
toasts_.erase(iter);
break;
diff --git a/ui/message_center/views/message_popup_collection.h b/ui/message_center/views/message_popup_collection.h
index 0f71a2f..b85bcf0 100644
--- a/ui/message_center/views/message_popup_collection.h
+++ b/ui/message_center/views/message_popup_collection.h
@@ -8,11 +8,10 @@
#include <list>
#include <map>
+#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
-#include "base/timer.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/message_center/message_center_export.h"
-#include "ui/message_center/notification_list.h"
-#include "ui/message_center/views/message_bubble_base.h"
#include "ui/views/widget/widget_observer.h"
namespace views {
@@ -25,6 +24,7 @@ FORWARD_DECLARE_TEST(WebNotificationTrayTest, ManyPopupNotifications);
namespace message_center {
+class MessageCenter;
class ToastContentsView;
// Container for popup toasts. Because each toast is a frameless window rather
@@ -38,7 +38,7 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
// |context| specifies the context to create toast windows. It can be NULL
// for non-aura environment. See comments in ui/views/widget/widget.h.
MessagePopupCollection(gfx::NativeView context,
- NotificationList::Delegate* list_delegate);
+ MessageCenter* message_center);
virtual ~MessagePopupCollection();
void UpdatePopups();
@@ -53,11 +53,11 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
void CloseAllWidgets();
- // views::WidgetObserver overrides:
+ // Overridden from views::WidgetObserver:
virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
gfx::NativeView context_;
- NotificationList::Delegate* list_delegate_;
+ MessageCenter* message_center_;
ToastContainer toasts_;
DISALLOW_COPY_AND_ASSIGN(MessagePopupCollection);
diff --git a/ui/message_center/views/message_simple_view.cc b/ui/message_center/views/message_simple_view.cc
index 3fe905a..9402eee 100644
--- a/ui/message_center/views/message_simple_view.cc
+++ b/ui/message_center/views/message_simple_view.cc
@@ -7,7 +7,6 @@
#include "grit/ui_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_list.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/image_view.h"
@@ -20,10 +19,9 @@ namespace message_center {
const SkColor kNotificationColor = SkColorSetRGB(0xfe, 0xfe, 0xfe);
const SkColor kNotificationReadColor = SkColorSetRGB(0xfa, 0xfa, 0xfa);
-MessageSimpleView::MessageSimpleView(
- NotificationList::Delegate* list_delegate,
- const Notification& notification)
- : MessageView(list_delegate, notification) {
+MessageSimpleView::MessageSimpleView(const Notification& notification,
+ NotificationChangeObserver* observer)
+ : MessageView(notification, observer, false) {
views::ImageButton* close = new views::ImageButton(this);
close->SetImage(
views::CustomButton::STATE_NORMAL,
@@ -64,7 +62,7 @@ void MessageSimpleView::SetUpView(const Notification& notification) {
views::ImageView* icon = new views::ImageView;
icon->SetImageSize(
gfx::Size(kWebNotificationIconSize, kWebNotificationIconSize));
- icon->SetImage(notification.primary_icon().AsImageSkia());
+ icon->SetImage(notification.icon().AsImageSkia());
views::Label* title = new views::Label(notification.title());
title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
diff --git a/ui/message_center/views/message_simple_view.h b/ui/message_center/views/message_simple_view.h
index 2a9e9b1..50cd5d3 100644
--- a/ui/message_center/views/message_simple_view.h
+++ b/ui/message_center/views/message_simple_view.h
@@ -5,18 +5,18 @@
#ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_SIMPLE_VIEW_H_
#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_SIMPLE_VIEW_H_
-#include "ui/message_center/notification_list.h"
#include "ui/message_center/views/message_view.h"
namespace message_center {
class Notification;
+class NotificationChangeObserver;
// A simple view for a notification entry (icon + message + buttons).
class MessageSimpleView : public MessageView {
public:
- MessageSimpleView(NotificationList::Delegate* list_delegate,
- const Notification& notification);
+ MessageSimpleView(const Notification& notification,
+ NotificationChangeObserver* observer);
virtual ~MessageSimpleView();
// Overridden from MessageView:
diff --git a/ui/message_center/views/message_view.cc b/ui/message_center/views/message_view.cc
index 0ea4f91..a8c1a63 100644
--- a/ui/message_center/views/message_view.cc
+++ b/ui/message_center/views/message_view.cc
@@ -14,6 +14,7 @@
#include "ui/gfx/shadow_value.h"
#include "ui/gfx/skia_util.h"
#include "ui/message_center/message_center_util.h"
+#include "ui/message_center/notification_change_observer.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/menu/menu_model_adapter.h"
#include "ui/views/controls/menu/menu_runner.h"
@@ -22,9 +23,12 @@
namespace {
-const int kCloseButtonSize = 29;
+const int kControlButtonSize = 29;
const int kCloseIconTopPadding = 5;
const int kCloseIconRightPadding = 5;
+const int kExpandIconBottomPadding = 8;
+const int kExpandIconRightPadding = 11;
+
const int kShadowOffset = 1;
const int kShadowBlur = 4;
@@ -104,7 +108,7 @@ void ControlButton::SetPressedImage(int resource_id) {
}
gfx::Size ControlButton::GetPreferredSize() {
- return gfx::Size(kCloseButtonSize, kCloseButtonSize);
+ return gfx::Size(kControlButtonSize, kControlButtonSize);
}
void ControlButton::OnPaint(gfx::Canvas* canvas) {
@@ -151,7 +155,7 @@ class ShadowBorder : public views::Border {
virtual ~ShadowBorder() {}
protected:
- // views::Border overrides:
+ // Overridden from views::Border:
virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE;
virtual gfx::Insets GetInsets() const OVERRIDE;
@@ -180,7 +184,7 @@ gfx::Insets ShadowBorder::GetInsets() const {
class MenuModel : public ui::SimpleMenuModel,
public ui::SimpleMenuModel::Delegate {
public:
- MenuModel(message_center::NotificationList::Delegate* list_delegate,
+ MenuModel(message_center::NotificationChangeObserver* observer,
const std::string& notification_id,
const string16& display_source,
const std::string& extension_id);
@@ -196,19 +200,18 @@ class MenuModel : public ui::SimpleMenuModel,
virtual void ExecuteCommand(int command_id) OVERRIDE;
private:
- message_center::NotificationList::Delegate* list_delegate_;
- // Weak, global MessageCenter
+ message_center::NotificationChangeObserver* observer_; // Weak reference.
std::string notification_id_;
DISALLOW_COPY_AND_ASSIGN(MenuModel);
};
-MenuModel::MenuModel(message_center::NotificationList::Delegate* list_delegate,
+MenuModel::MenuModel(message_center::NotificationChangeObserver* observer,
const std::string& notification_id,
const string16& display_source,
const std::string& extension_id)
: ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)),
- list_delegate_(list_delegate),
+ observer_(observer),
notification_id_(notification_id) {
// Add 'disable notifications' menu item.
if (!extension_id.empty()) {
@@ -249,13 +252,13 @@ bool MenuModel::GetAcceleratorForCommandId(int command_id,
void MenuModel::ExecuteCommand(int command_id) {
switch (command_id) {
case kToggleExtensionCommand:
- list_delegate_->DisableNotificationByExtension(notification_id_);
+ observer_->OnDisableNotificationsByExtension(notification_id_);
break;
case kTogglePermissionCommand:
- list_delegate_->DisableNotificationByUrl(notification_id_);
+ observer_->OnDisableNotificationsByUrl(notification_id_);
break;
case kShowSettingsCommand:
- list_delegate_->ShowNotificationSettings(notification_id_);
+ observer_->OnShowNotificationSettings(notification_id_);
break;
default:
NOTREACHED();
@@ -266,19 +269,31 @@ void MenuModel::ExecuteCommand(int command_id) {
namespace message_center {
-MessageView::MessageView(NotificationList::Delegate* list_delegate,
- const Notification& notification)
- : list_delegate_(list_delegate),
+MessageView::MessageView(const Notification& notification,
+ NotificationChangeObserver* observer,
+ bool expanded)
+ : observer_(observer),
notification_id_(notification.id()),
display_source_(notification.display_source()),
extension_id_(notification.extension_id()),
- scroller_(NULL) {
+ scroller_(NULL),
+ is_expanded_(expanded) {
ControlButton *close = new ControlButton(this);
close->SetPadding(-kCloseIconRightPadding, kCloseIconTopPadding);
close->SetNormalImage(IDR_NOTIFICATION_CLOSE);
close->SetHoveredImage(IDR_NOTIFICATION_CLOSE_HOVER);
close->SetPressedImage(IDR_NOTIFICATION_CLOSE_PRESSED);
+ close->set_owned_by_client();
close_button_.reset(close);
+
+ ControlButton *expand = new ControlButton(this);
+ expand->SetPadding(-kExpandIconRightPadding, -kExpandIconBottomPadding);
+ expand->SetNormalImage(IDR_NOTIFICATIONS_EXPAND);
+ expand->SetHoveredImage(IDR_NOTIFICATIONS_EXPAND_HOVER);
+ expand->SetPressedImage(IDR_NOTIFICATIONS_EXPAND_PRESSED);
+ expand->set_owned_by_client();
+ expand_button_.reset(expand);
+
if (IsRichNotificationEnabled())
set_border(new ShadowBorder());
}
@@ -297,18 +312,24 @@ gfx::Insets MessageView::GetShadowInsets() {
kShadowBlur / 2);
}
+void MessageView::Update(const Notification& notification) {
+ notification_id_ = notification.id();
+ display_source_ = notification.display_source();
+ extension_id_ = notification.extension_id();
+}
+
bool MessageView::OnMousePressed(const ui::MouseEvent& event) {
if (event.flags() & ui::EF_RIGHT_MOUSE_BUTTON) {
ShowMenu(event.location());
return true;
}
- list_delegate_->OnNotificationClicked(notification_id_);
+ observer_->OnClicked(notification_id_);
return true;
}
void MessageView::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_TAP) {
- list_delegate_->OnNotificationClicked(notification_id_);
+ observer_->OnClicked(notification_id_);
event->SetHandled();
return;
}
@@ -334,12 +355,16 @@ void MessageView::OnGestureEvent(ui::GestureEvent* event) {
void MessageView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
- if (sender == close_button())
- list_delegate_->SendRemoveNotification(notification_id_, true); // By user.
+ if (sender == close_button()) {
+ observer_->OnRemoveNotification(notification_id_, true); // By user.
+ } else if (sender == expand_button()) {
+ is_expanded_ = true;
+ observer_->OnExpanded(notification_id_);
+ }
}
void MessageView::ShowMenu(gfx::Point screen_location) {
- MenuModel menu_model(list_delegate_, notification_id_,
+ MenuModel menu_model(observer_, notification_id_,
display_source_, extension_id_);
if (menu_model.GetItemCount() == 0)
return;
@@ -357,7 +382,7 @@ void MessageView::ShowMenu(gfx::Point screen_location) {
}
void MessageView::OnSlideOut() {
- list_delegate_->SendRemoveNotification(notification_id_, true); // By user.
+ observer_->OnRemoveNotification(notification_id_, true); // By user.
}
} // namespace message_center
diff --git a/ui/message_center/views/message_view.h b/ui/message_center/views/message_view.h
index 86920b9..37725db 100644
--- a/ui/message_center/views/message_view.h
+++ b/ui/message_center/views/message_view.h
@@ -7,18 +7,19 @@
#include "ui/gfx/insets.h"
#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_list.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/slide_out_view.h"
-#include "ui/views/view.h"
namespace views {
class ImageButton;
+class ImageView;
class ScrollView;
}
namespace message_center {
+class NotificationChangeObserver;
+
// Individual notifications constants.
const int kPaddingBetweenItems = 10;
const int kPaddingHorizontal = 18;
@@ -30,52 +31,59 @@ const int kWebNotificationWidth = 300;
class MessageView : public views::SlideOutView,
public views::ButtonListener {
public:
- MessageView(NotificationList::Delegate* list_delegate,
- const Notification& notification);
-
+ MessageView(const Notification& notification,
+ NotificationChangeObserver* observer,
+ bool expanded);
virtual ~MessageView();
// Returns the insets for the shadow it will have for rich notification.
static gfx::Insets GetShadowInsets();
- void set_scroller(views::ScrollView* scroller) { scroller_ = scroller; }
+ // Adjust to any change in notification data or expanded status.
+ virtual void Update(const Notification& notification);
- // Overridden from views::View.
+ // Overridden from views::View:
virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
- // Overridden from ui::EventHandler.
+ // Overridden from ui::EventHandler:
virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
- // Overridden from ButtonListener.
+ // Overridden from ButtonListener:
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;
+ void set_scroller(views::ScrollView* scroller) { scroller_ = scroller; }
+
protected:
MessageView();
// Shows the menu for the notification.
void ShowMenu(gfx::Point screen_location);
- // Overridden from views::SlideOutView.
+ // Overridden from views::SlideOutView:
virtual void OnSlideOut() OVERRIDE;
- NotificationList::Delegate* list_delegate() { return list_delegate_; }
+ NotificationChangeObserver* observer() { return observer_; }
const std::string& notification_id() { return notification_id_; }
const string16& display_source() const { return display_source_; }
const std::string& extension_id() const { return extension_id_; }
views::ImageButton* close_button() { return close_button_.get(); }
+ views::ImageButton* expand_button() { return expand_button_.get(); }
views::ScrollView* scroller() { return scroller_; }
+ const bool is_expanded() { return is_expanded_; }
private:
- NotificationList::Delegate* list_delegate_; // Weak, global (MessageCenter).
+ NotificationChangeObserver* observer_; // Weak reference.
std::string notification_id_;
string16 display_source_;
std::string extension_id_;
scoped_ptr<views::ImageButton> close_button_;
-
+ scoped_ptr<views::ImageButton> expand_button_;
views::ScrollView* scroller_;
+ bool is_expanded_;
+
DISALLOW_COPY_AND_ASSIGN(MessageView);
};
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc
index e4b2cca..268bd35 100644
--- a/ui/message_center/views/notification_view.cc
+++ b/ui/message_center/views/notification_view.cc
@@ -10,11 +10,13 @@
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/text/text_elider.h"
+#include "ui/gfx/canvas.h"
#include "ui/gfx/size.h"
#include "ui/message_center/message_center_constants.h"
#include "ui/message_center/message_center_switches.h"
#include "ui/message_center/message_center_util.h"
#include "ui/message_center/notification.h"
+#include "ui/message_center/notification_change_observer.h"
#include "ui/message_center/notification_types.h"
#include "ui/message_center/views/message_simple_view.h"
#include "ui/native_theme/native_theme.h"
@@ -96,17 +98,22 @@ ItemView::ItemView(const message_center::NotificationItem& item) {
ItemView::~ItemView() {
}
-// ProportionalImageViews match their heights to their widths to preserve the
-// proportions of their images.
+// ProportionalImageViews center their images to preserve their proportion.
+// Note that for this subclass of views::ImageView GetImageBounds() will return
+// potentially incorrect values (this can't be fixed because GetImageBounds()
+// is not virtual) and horizontal and vertical alignments will be ignored.
class ProportionalImageView : public views::ImageView {
public:
ProportionalImageView();
virtual ~ProportionalImageView();
- // Overridden from views::View.
+ // Overridden from views::View:
virtual int GetHeightForWidth(int width) OVERRIDE;
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
private:
+ gfx::Size GetImageSizeForWidth(int width);
+
DISALLOW_COPY_AND_ASSIGN(ProportionalImageView);
};
@@ -117,18 +124,42 @@ ProportionalImageView::~ProportionalImageView() {
}
int ProportionalImageView::GetHeightForWidth(int width) {
- int height = 0;
- gfx::ImageSkia image = GetImage();
- if (image.width() > 0 && image.height() > 0) {
- double proportion = image.height() / (double) image.width();
- height = 0.5 + width * proportion;
- if (height > message_center::kNotificationMaximumImageHeight) {
- height = message_center::kNotificationMaximumImageHeight;
- width = 0.5 + height / proportion;
+ return GetImageSizeForWidth(width).height();
+}
+
+void ProportionalImageView::OnPaint(gfx::Canvas* canvas) {
+ View::OnPaint(canvas);
+
+ gfx::Size draw_size(GetImageSizeForWidth(width()));
+ if (!draw_size.IsEmpty()) {
+ int x = (width() - draw_size.width()) / 2;
+ int y = (height() - draw_size.height()) / 2;
+
+ gfx::Size image_size(GetImage().size());
+ if (image_size == draw_size) {
+ canvas->DrawImageInt(GetImage(), x, y);
+ } else {
+ // Resize case
+ SkPaint paint;
+ paint.setFilterBitmap(true);
+ canvas->DrawImageInt(GetImage(), 0, 0,
+ image_size.width(), image_size.height(), x, y,
+ draw_size.width(), draw_size.height(), true, paint);
+ }
+ }
+}
+
+gfx::Size ProportionalImageView::GetImageSizeForWidth(int width) {
+ gfx::Size size(GetImage().size());
+ if (width > 0 && !size.IsEmpty()) {
+ double proportion = size.height() / (double) size.width();
+ size.SetSize(width, std::max(0.5 + width * proportion, 1.0));
+ if (size.height() > message_center::kNotificationMaximumImageHeight) {
+ int height = message_center::kNotificationMaximumImageHeight;
+ size.SetSize(std::max(0.5 + height / proportion, 1.0), height);
}
- SetImageSize(gfx::Size(width, height));
}
- return height;
+ return size;
}
// NotificationsButtons render the action buttons of notifications.
@@ -196,9 +227,9 @@ void NotificationButton::SetTitle(const string16& title) {
namespace message_center {
// static
-MessageView* NotificationView::Create(
- const Notification& notification,
- NotificationList::Delegate* list_delegate) {
+MessageView* NotificationView::Create(const Notification& notification,
+ NotificationChangeObserver* observer,
+ bool expanded) {
// For the time being, use MessageSimpleView for simple notifications unless
// one of the use-the-new-style flags are set. This preserves the appearance
// of notifications created by existing code that uses webkitNotifications.
@@ -206,7 +237,7 @@ MessageView* NotificationView::Create(
!IsRichNotificationEnabled() &&
!CommandLine::ForCurrentProcess()->HasSwitch(
message_center::switches::kEnableNewSimpleNotifications)) {
- return new MessageSimpleView(list_delegate, notification);
+ return new MessageSimpleView(notification, observer);
}
switch (notification.type()) {
@@ -227,61 +258,89 @@ MessageView* NotificationView::Create(
}
// Currently all roads lead to the generic NotificationView.
- return new NotificationView(list_delegate, notification);
+ return new NotificationView(notification, observer, expanded);
}
-NotificationView::NotificationView(NotificationList::Delegate* list_delegate,
- const Notification& notification)
- : MessageView(list_delegate, notification) {
- // This view is composed of two layers: The first layer has the notification
- // content (text, images, action buttons, ...). This is overlaid by a second
- // layer that has the notification close button and will later also have the
- // expand button. This allows the close and expand buttons to overlap the
- // content as needed to provide a large enough click area
- // (<http://crbug.com/168822> and touch area <http://crbug.com/168856>).
- AddChildView(MakeContentView(notification));
- AddChildView(close_button());
+NotificationView::NotificationView(const Notification& notification,
+ NotificationChangeObserver* observer,
+ bool expanded)
+ : MessageView(notification, observer, expanded),
+ content_view_(NULL),
+ icon_view_(NULL) {
+ AddChildViews(notification);
}
NotificationView::~NotificationView() {
}
void NotificationView::Layout() {
- if (content_view_) {
- gfx::Rect contents_bounds = GetContentsBounds();
- content_view_->SetBoundsRect(contents_bounds);
- if (close_button()) {
- gfx::Size size(close_button()->GetPreferredSize());
- close_button()->SetBounds(contents_bounds.right() - size.width(), 0,
- size.width(), size.height());
- }
- }
+ gfx::Rect content_bounds(GetLocalBounds());
+ content_bounds.Inset(GetInsets());
+ content_view_->SetBoundsRect(content_bounds);
+
+ gfx::Size close_size(close_button()->GetPreferredSize());
+ close_button()->SetBounds(content_bounds.right() - close_size.width(),
+ content_bounds.y(),
+ close_size.width(),
+ close_size.height());
+
+ gfx::Rect icon_bounds(content_bounds.origin(), icon_view_->size());
+ gfx::Size expand_size(expand_button()->GetPreferredSize());
+ expand_button()->SetBounds(content_bounds.right() - expand_size.width(),
+ icon_bounds.bottom() - expand_size.height(),
+ expand_size.width(),
+ expand_size.height());
}
gfx::Size NotificationView::GetPreferredSize() {
- if (!content_view_)
- return gfx::Size();
- gfx::Size size = content_view_->GetPreferredSize();
- if (border()) {
- gfx::Insets border_insets = border()->GetInsets();
- size.Enlarge(border_insets.width(), border_insets.height());
+ gfx::Size size;
+ if (content_view_) {
+ size = content_view_->GetPreferredSize();
+ if (border()) {
+ gfx::Insets insets = border()->GetInsets();
+ size.Enlarge(insets.width(), insets.height());
+ }
}
return size;
}
+void NotificationView::Update(const Notification& notification) {
+ MessageView::Update(notification);
+ content_view_ = NULL;
+ icon_view_ = NULL;
+ action_buttons_.clear();
+ RemoveAllChildViews(true);
+ AddChildViews(notification);
+ PreferredSizeChanged();
+ SchedulePaint();
+}
+
void NotificationView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
for (size_t i = 0; i < action_buttons_.size(); ++i) {
- if (action_buttons_[i] == sender) {
- list_delegate()->OnButtonClicked(notification_id(), i);
+ if (sender == action_buttons_[i]) {
+ observer()->OnButtonClicked(notification_id(), i);
return;
}
}
MessageView::ButtonPressed(sender, event);
}
-views::View* NotificationView::MakeContentView(
- const Notification& notification) {
+void NotificationView::AddChildViews(const Notification& notification) {
+ // Child views are in two layers: The first layer has the notification content
+ // (text, images, action buttons, ...). This is overlaid by a second layer
+ // that has the notification close and expand buttons. This allows the close
+ // and expand buttons to overlap the content as needed to provide large enough
+ // click and touch areas (<http://crbug.com/168822> and
+ // <http://crbug.com/168856>).
+ AddContentView(notification);
+ AddChildView(close_button());
+ if (!is_expanded()) {
+ AddChildView(expand_button());
+ }
+}
+
+void NotificationView::AddContentView(const Notification& notification) {
content_view_ = new views::View();
content_view_->set_background(
views::Background::CreateSolidBackground(kBackgroundColor));
@@ -291,39 +350,44 @@ views::View* NotificationView::MakeContentView(
// items), followed by a padding view. Laying out the icon view will require
// information about the text views, so these are created first and collected
// in this vector.
- std::vector<views::View*> texts;
+ std::vector<views::View*> text_views;
// Title if it exists.
if (!notification.title().empty()) {
views::Label* title = new views::Label(notification.title());
title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- title->SetElideBehavior(views::Label::ELIDE_AT_END);
+ if (is_expanded())
+ title->SetMultiLine(true);
+ else
+ title->SetElideBehavior(views::Label::ELIDE_AT_END);
title->SetFont(title->font().DeriveFont(4));
title->SetEnabledColor(kTitleColor);
title->SetBackgroundColor(kTitleBackgroundColor);
title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextRightPadding));
- texts.push_back(title);
+ text_views.push_back(title);
+ }
+
+ // List notification items up to a maximum if appropriate.
+ size_t maximum = is_expanded() ? kNotificationMaximumItems : 0ul;
+ size_t items = std::min(notification.items().size(), maximum);
+ for (size_t i = 0; i < items; ++i) {
+ ItemView* item = new ItemView(notification.items()[i]);
+ item->set_border(MakePadding(0, 0, 4, kTextRightPadding));
+ text_views.push_back(item);
}
// Message if appropriate.
- if (notification.items().size() == 0 &&
- !notification.message().empty()) {
+ if (items == 0ul && !notification.message().empty()) {
views::Label* message = new views::Label(notification.message());
message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- message->SetMultiLine(true);
+ if (is_expanded())
+ message->SetMultiLine(true);
+ else
+ message->SetElideBehavior(views::Label::ELIDE_AT_END);
message->SetEnabledColor(kMessageColor);
message->SetBackgroundColor(kMessageBackgroundColor);
message->set_border(MakePadding(0, 0, 3, kTextRightPadding));
- texts.push_back(message);
- }
-
- // List notification items up to a maximum.
- int items = std::min(notification.items().size(),
- kNotificationMaximumItems);
- for (int i = 0; i < items; ++i) {
- ItemView* item = new ItemView(notification.items()[i]);
- item->set_border(MakePadding(0, 0, 4, kTextRightPadding));
- texts.push_back(item);
+ text_views.push_back(message);
}
// Set up the content view with a fixed-width icon column on the left and a
@@ -345,28 +409,28 @@ views::View* NotificationView::MakeContentView(
// Create the first row and its icon view, which spans all the text views
// to its right as well as the padding view below them.
layout->StartRow(0, 0);
- views::ImageView* icon = new views::ImageView();
- icon->SetImageSize(gfx::Size(message_center::kNotificationIconSize,
- message_center::kNotificationIconSize));
- icon->SetImage(notification.primary_icon().AsImageSkia());
- icon->SetHorizontalAlignment(views::ImageView::LEADING);
- icon->SetVerticalAlignment(views::ImageView::LEADING);
- icon->set_border(MakePadding(0, 0, 0, kIconToTextPadding));
- layout->AddView(icon, 1, texts.size() + 1);
+ icon_view_ = new views::ImageView();
+ icon_view_->SetImageSize(gfx::Size(message_center::kNotificationIconSize,
+ message_center::kNotificationIconSize));
+ icon_view_->SetImage(notification.icon().AsImageSkia());
+ icon_view_->SetHorizontalAlignment(views::ImageView::LEADING);
+ icon_view_->SetVerticalAlignment(views::ImageView::LEADING);
+ icon_view_->set_border(MakePadding(0, 0, 0, kIconToTextPadding));
+ layout->AddView(icon_view_, 1, text_views.size() + 1);
// Add the text views, creating rows for them if necessary.
- for (size_t i = 0; i < texts.size(); ++i) {
+ for (size_t i = 0; i < text_views.size(); ++i) {
if (i > 0) {
layout->StartRow(0, 0);
layout->SkipColumns(1);
}
- layout->AddView(texts[i]);
+ layout->AddView(text_views[i]);
}
// Add a text padding row if necessary. This adds some space between the last
// line of text and anything below it but it also ensures views above it are
// top-justified by expanding vertically to take up any extra space.
- if (texts.size() == 0) {
+ if (text_views.size() == 0) {
layout->SkipColumns(1);
} else {
layout->StartRow(100, 0);
@@ -377,14 +441,11 @@ views::View* NotificationView::MakeContentView(
}
// Add an image row if appropriate.
- if (!notification.image().IsEmpty()) {
+ if (is_expanded() && !notification.image().IsEmpty()) {
layout->StartRow(0, 0);
- views::ImageView* image = new ProportionalImageView();
- image->SetImageSize(notification.image().ToImageSkia()->size());
- image->SetImage(notification.image().ToImageSkia());
- image->SetHorizontalAlignment(views::ImageView::CENTER);
- image->SetVerticalAlignment(views::ImageView::LEADING);
- layout->AddView(image, 2, 1);
+ ProportionalImageView* image_view = new ProportionalImageView();
+ image_view->SetImage(notification.image().ToImageSkia());
+ layout->AddView(image_view, 2, 1);
}
// Add action button rows.
@@ -404,7 +465,7 @@ views::View* NotificationView::MakeContentView(
views::GridLayout::FILL, views::GridLayout::FILL, 0, 40);
}
- return content_view_;
+ AddChildView(content_view_);
}
} // namespace message_center
diff --git a/ui/message_center/views/notification_view.h b/ui/message_center/views/notification_view.h
index dee7e98..a0b23e9 100644
--- a/ui/message_center/views/notification_view.h
+++ b/ui/message_center/views/notification_view.h
@@ -5,40 +5,49 @@
#ifndef UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_VIEW_H_
#define UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_VIEW_H_
-#include "ui/message_center/notification_list.h"
+#include <vector>
+
#include "ui/message_center/views/message_view.h"
namespace message_center {
+class NotificationChangeObserver;
+
// View that displays all current types of notification (web, basic, image, and
// list). Future notification types may be handled by other classes, in which
-// case instances of those classes would be returned by the
-// ViewForNotification() factory method below.
+// case instances of those classes would be returned by the Create() factory
+// method below.
class NotificationView : public MessageView {
public:
// Creates appropriate MessageViews for notifications. Those currently are
- // always NotificationView instances but in the future may be instances of
- // other classes, with the class depending on the notification type.
+ // always NotificationView or MessageSimpleView instances but in the future
+ // may be instances of other classes, with the class depending on the
+ // notification type.
static MessageView* Create(const Notification& notification,
- NotificationList::Delegate* list_delegate);
+ NotificationChangeObserver* observer,
+ bool expanded);
virtual ~NotificationView();
- // Overridden from View.
+ // Overridden from views::View:
virtual void Layout() OVERRIDE;
virtual gfx::Size GetPreferredSize() OVERRIDE;
- // Overridden from MessageView.
+ // Overridden from MessageView:
+ virtual void Update(const Notification& notification) OVERRIDE;
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;
private:
- NotificationView(NotificationList::Delegate* list_delegate,
- const Notification& notification);
+ NotificationView(const Notification& notification,
+ NotificationChangeObserver* observer,
+ bool expanded);
- views::View* MakeContentView(const Notification& notification);
+ void AddChildViews(const Notification& notification);
+ void AddContentView(const Notification& notification);
views::View* content_view_;
+ views::ImageView* icon_view_;
std::vector<views::Button*> action_buttons_;
DISALLOW_COPY_AND_ASSIGN(NotificationView);
diff --git a/ui/message_center/views/notifier_settings_view.cc b/ui/message_center/views/notifier_settings_view.cc
index 3de1f0b..c65d4e0 100644
--- a/ui/message_center/views/notifier_settings_view.cc
+++ b/ui/message_center/views/notifier_settings_view.cc
@@ -83,7 +83,7 @@ class NotifierSettingsView::NotifierButton : public views::CustomButton,
}
private:
- // views::ButtonListener overrides:
+ // Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* button,
const ui::Event& event) OVERRIDE {
DCHECK(button == checkbox_);
diff --git a/ui/message_center/views/notifier_settings_view.h b/ui/message_center/views/notifier_settings_view.h
index a296dd5..4aa7701 100644
--- a/ui/message_center/views/notifier_settings_view.h
+++ b/ui/message_center/views/notifier_settings_view.h
@@ -45,13 +45,13 @@ class MESSAGE_CENTER_EXPORT NotifierSettingsView
NotifierSettingsView(NotifierSettingsViewDelegate* delegate);
virtual ~NotifierSettingsView();
- // views::WidgetDelegate overrides:
+ // Overridden from views::WidgetDelegate:
virtual bool CanResize() const OVERRIDE;
virtual string16 GetWindowTitle() const OVERRIDE;
virtual void WindowClosing() OVERRIDE;
virtual views::View* GetContentsView() OVERRIDE;
- // views::ButtonListener overrides:
+ // Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;