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

Unified Diff: chrome/browser/ui/views/message_center/web_notification_tray.cc

Issue 18003003: Message center re-organized (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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: chrome/browser/ui/views/message_center/web_notification_tray.cc
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray.cc b/chrome/browser/ui/views/message_center/web_notification_tray.cc
index bd3e21a4f60c7c145ff6fa0f207d3809c86f0302..eb6522724592b1c3b6c7024d34934eb7207506e8 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray.cc
+++ b/chrome/browser/ui/views/message_center/web_notification_tray.cc
@@ -10,13 +10,11 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/status_icons/status_icon.h"
#include "chrome/browser/status_icons/status_tray.h"
-#include "chrome/browser/ui/views/message_center/notification_bubble_wrapper.h"
#include "content/public/browser/user_metrics.h"
#include "grit/chromium_strings.h"
#include "grit/theme_resources.h"
#include "grit/ui_strings.h"
#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/models/simple_menu_model.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia_operations.h"
@@ -25,8 +23,6 @@
#include "ui/gfx/size.h"
#include "ui/message_center/message_center_tray.h"
#include "ui/message_center/message_center_tray_delegate.h"
-#include "ui/message_center/views/message_bubble_base.h"
-#include "ui/message_center/views/message_center_bubble.h"
#include "ui/message_center/views/message_popup_collection.h"
#include "ui/views/widget/widget.h"
@@ -39,15 +35,50 @@ const int kSystemTrayWidth = 16;
const int kSystemTrayHeight = 16;
const int kNumberOfSystemTraySprites = 10;
-gfx::Rect GetCornerAnchorRect() {
- // TODO(dewittj): Use the preference to determine which corner to anchor from.
+gfx::ImageSkia GetIcon(int unread_count) {
+ bool has_unread = unread_count > 0;
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ if (!has_unread)
+ return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY);
+
+ return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_ATTENTION);
+}
+
+} // namespace
+
+using content::UserMetricsAction;
+
+namespace message_center {
+
+namespace internal {
+
+// Gets the position of the taskbar from the work area bounds. Returns
+// ALIGNMENT_NONE if position cannot be found.
+Alignment GetTaskbarAlignment() {
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
- gfx::Rect rect = screen->GetPrimaryDisplay().work_area();
- rect.Inset(kScreenEdgePadding, kScreenEdgePadding);
- return gfx::Rect(rect.bottom_right(), gfx::Size());
+ // TODO(dewittj): It's possible GetPrimaryDisplay is wrong.
+ gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds();
+ gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
+ work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
+
+ // Comparing the work area to the screen bounds gives us the location of the
+ // taskbar. If the work area is exactly the same as the screen bounds,
+ // we are unable to locate the taskbar so we say we don't know it's alignment.
+ if (work_area.height() < screen_bounds.height()) {
+ if (work_area.y() > screen_bounds.y())
+ return ALIGNMENT_TOP;
+ return ALIGNMENT_BOTTOM;
+ }
+ if (work_area.width() < screen_bounds.width()) {
+ if (work_area.x() > screen_bounds.x())
+ return ALIGNMENT_LEFT;
+ return ALIGNMENT_RIGHT;
+ }
+
+ return ALIGNMENT_NONE;
}
-gfx::Point GetClosestCorner(gfx::Rect rect, gfx::Point query) {
+gfx::Point GetClosestCorner(const gfx::Rect& rect, const gfx::Point& query) {
gfx::Point center_point = rect.CenterPoint();
gfx::Point rv;
@@ -64,41 +95,28 @@ gfx::Point GetClosestCorner(gfx::Rect rect, gfx::Point query) {
return rv;
}
-// GetMouseAnchorRect returns a rectangle that has one corner where the mouse
-// clicked, and the opposite corner at the closest corner of the work area
-// (inset by an appropriate margin.)
-gfx::Rect GetMouseAnchorRect(gfx::Point cursor) {
- // TODO(dewittj): GetNativeScreen could be wrong for Aura.
- gfx::Screen* screen = gfx::Screen::GetNativeScreen();
- gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
- work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
- gfx::Point corner = GetClosestCorner(work_area, cursor);
+// Gets the corner of the screen where the message center should pop up.
+Alignment GetAnchorAlignment(const gfx::Rect& work_area, gfx::Point corner) {
+ gfx::Point center = work_area.CenterPoint();
- gfx::Rect mouse_anchor_rect(gfx::BoundingRect(cursor, corner));
- return mouse_anchor_rect;
-}
-
-gfx::ImageSkia GetIcon(int unread_count) {
- bool has_unread = unread_count > 0;
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- if (!has_unread)
- return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY);
+ Alignment anchor_alignment =
+ center.y() > corner.y() ? ALIGNMENT_TOP : ALIGNMENT_BOTTOM;
+ anchor_alignment =
+ (Alignment)(anchor_alignment |
+ (center.x() > corner.x() ? ALIGNMENT_LEFT : ALIGNMENT_RIGHT));
- return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_ATTENTION);
+ return anchor_alignment;
}
-} // namespace
-
-using content::UserMetricsAction;
-
-namespace message_center {
+} // namespace internal
MessageCenterTrayDelegate* CreateMessageCenterTray() {
return new WebNotificationTray();
}
WebNotificationTray::WebNotificationTray()
- : status_icon_(NULL),
+ : message_center_delegate_(NULL),
+ status_icon_(NULL),
message_center_visible_(false),
should_update_tray_content_(true) {
message_center_tray_.reset(
@@ -128,60 +146,36 @@ void WebNotificationTray::HidePopups() { popup_collection_.reset(); }
bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) {
content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter"));
- // Using MessageBubbleBase instead of MessageCenterBubble to
- // remove dependence on implicit type conversion
- scoped_ptr<message_center::MessageCenterBubble> bubble(
- new message_center::MessageCenterBubble(message_center(),
- message_center_tray_.get()));
-
- gfx::Screen* screen = gfx::Screen::GetNativeScreen();
- gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
- views::TrayBubbleView::AnchorAlignment alignment = GetAnchorAlignment();
-
- int max_height = work_area.height();
-
- // If the alignment is left- or right-oriented, the bubble can fill up the
- // entire vertical height of the screen since the bubble is rendered to the
- // side of the clicked icon. Otherwise we have to adjust for the arrow's
- // height.
- if (alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM ||
- alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_TOP) {
- max_height -= 2 * kScreenEdgePadding;
-
- // If the work area contains the click point, then we know that the icon is
- // not in the taskbar. Then we need to subtract the distance of the click
- // point from the edge of the work area so we can see the whole bubble.
- if (work_area.Contains(mouse_click_point_)) {
- max_height -= std::min(mouse_click_point_.y() - work_area.y(),
- work_area.bottom() - mouse_click_point_.y());
- }
- }
- bubble->SetMaxHeight(max_height);
- if (show_settings)
- bubble->SetSettingsVisible();
-
- message_center_bubble_.reset(new internal::NotificationBubbleWrapper(
+ // Message center delegate will be set to NULL when the message center
+ // widget's Close method is called so we don't need to worry about
+ // use-after-free issues.
+ message_center_delegate_ = new MessageCenterWidgetDelegate(
this,
- bubble.PassAs<message_center::MessageBubbleBase>(),
- internal::NotificationBubbleWrapper::BUBBLE_TYPE_MESSAGE_CENTER));
+ message_center_tray_.get(),
+ show_settings, // settings initally invisible
+ GetPositionInfo());
+
return true;
}
bool WebNotificationTray::ShowMessageCenter() {
- return ShowMessageCenterInternal(false /* show_settings */);
+ return ShowMessageCenterInternal(/*show_settings =*/false);
}
void WebNotificationTray::HideMessageCenter() {
- message_center_bubble_.reset();
+ if (message_center_delegate_) {
+ views::Widget* widget = message_center_delegate_->GetWidget();
+ if (widget)
+ widget->Close();
+ }
}
bool WebNotificationTray::ShowNotifierSettings() {
- if (message_center_bubble_) {
- static_cast<MessageCenterBubble*>(
- message_center_bubble_->bubble())->SetSettingsVisible();
+ if (message_center_delegate_) {
+ message_center_delegate_->SetSettingsVisible(true);
return true;
}
- return ShowMessageCenterInternal(true /* show_settings */);
+ return ShowMessageCenterInternal(/*show_settings =*/true);
}
void WebNotificationTray::OnMessageCenterTrayChanged() {
@@ -193,36 +187,13 @@ void WebNotificationTray::OnMessageCenterTrayChanged() {
base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr()));
}
-gfx::Rect WebNotificationTray::GetMessageCenterAnchor() {
- return GetMouseAnchorRect(mouse_click_point_);
-}
-
-gfx::Rect WebNotificationTray::GetPopupAnchor() {
- return GetCornerAnchorRect();
-}
-
-views::TrayBubbleView::AnchorAlignment
-WebNotificationTray::GetAnchorAlignment() {
+void WebNotificationTray::OnStatusIconClicked() {
+ // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura.
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
- // TODO(dewittj): It's possible GetPrimaryDisplay is wrong.
- gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds();
- gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
-
- // Comparing the work area to the screen bounds gives us the location of the
- // taskbar. If the work area is less tall than the screen, assume the taskbar
- // is on the bottom, and cause the arrow to be displayed on the bottom of the
- // bubble. Otherwise, cause the arrow to be displayed on the side of the
- // bubble that the taskbar is on.
- if (work_area.width() < screen_bounds.width()) {
- if (work_area.x() > screen_bounds.x())
- return views::TrayBubbleView::ANCHOR_ALIGNMENT_LEFT;
- return views::TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT;
- }
- return views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
+ mouse_click_point_ = screen->GetCursorScreenPoint();
+ message_center_tray_->ToggleMessageCenterBubble();
}
-gfx::NativeView WebNotificationTray::GetBubbleWindowContainer() { return NULL; }
-
void WebNotificationTray::UpdateStatusIcon() {
if (!should_update_tray_content_)
return;
@@ -252,19 +223,54 @@ void WebNotificationTray::UpdateStatusIcon() {
}
}
-void WebNotificationTray::OnStatusIconClicked() {
- // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura.
- gfx::Screen* screen = gfx::Screen::GetNativeScreen();
- mouse_click_point_ = screen->GetCursorScreenPoint();
- message_center_tray_->ToggleMessageCenterBubble();
+void WebNotificationTray::SendHideMessageCenter() {
+ message_center_tray_->HideMessageCenterBubble();
}
-void WebNotificationTray::HideBubbleWithView(
- const views::TrayBubbleView* bubble_view) {
- if (message_center_bubble_.get() &&
- bubble_view == message_center_bubble_->bubble_view()) {
- message_center_tray_->HideMessageCenterBubble();
+void WebNotificationTray::MarkMessageCenterHidden() {
+ if (message_center_delegate_) {
+ message_center_tray_->MarkMessageCenterHidden();
+ message_center_delegate_ = NULL;
+ }
+}
+
+PositionInfo WebNotificationTray::GetPositionInfo() {
+ PositionInfo pos_info;
+
+ gfx::Screen* screen = gfx::Screen::GetNativeScreen();
+ gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
+ work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
+
+ gfx::Point corner = internal::GetClosestCorner(work_area, mouse_click_point_);
+
+ pos_info.taskbar_alignment = internal::GetTaskbarAlignment();
+
+ // We assume the taskbar is either at the top or at the bottom if we are not
+ // able to find it.
+ if (pos_info.taskbar_alignment == ALIGNMENT_NONE) {
+ if (mouse_click_point_.y() > corner.y())
+ pos_info.taskbar_alignment = ALIGNMENT_TOP;
+ else
+ pos_info.taskbar_alignment = ALIGNMENT_BOTTOM;
}
+
+ pos_info.message_center_alignment =
+ internal::GetAnchorAlignment(work_area, corner);
+
+ pos_info.inital_anchor_point = corner;
+ pos_info.max_height = work_area.height();
+
+ if (work_area.Contains(mouse_click_point_)) {
+ pos_info.max_height -= std::abs(mouse_click_point_.y() - corner.y());
+
+ // Message center is in the work area. So position it few pixels above the
+ // mouse click point if alignemnt is towards bottom and few pixels below if
+ // alignment is towards top.
+ pos_info.inital_anchor_point
+ .set_y(mouse_click_point_.y() +
+ (pos_info.message_center_alignment & ALIGNMENT_BOTTOM ? -5 : 5));
+ }
+ return pos_info;
}
StatusIcon* WebNotificationTray::GetStatusIcon() {
@@ -302,12 +308,9 @@ void WebNotificationTray::AddQuietModeMenu(StatusIcon* status_icon) {
status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu());
}
-message_center::MessageCenterBubble*
-WebNotificationTray::GetMessageCenterBubbleForTest() {
- if (!message_center_bubble_.get())
- return NULL;
- return static_cast<message_center::MessageCenterBubble*>(
- message_center_bubble_->bubble());
+MessageCenterWidgetDelegate*
+WebNotificationTray::GetMessageCenterWidgetDelegateForTest() {
+ return message_center_delegate_;
}
} // namespace message_center

Powered by Google App Engine
This is Rietveld 408576698