| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/message_center/web_notification_tray.h" | 5 #include "chrome/browser/ui/views/message_center/web_notification_tray.h" |
| 6 | 6 |
| 7 #include "base/i18n/number_formatting.h" | 7 #include "base/i18n/number_formatting.h" |
| 8 #include "base/strings/string16.h" | 8 #include "base/strings/string16.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
| 11 #include "chrome/browser/status_icons/status_icon.h" | 11 #include "chrome/browser/status_icons/status_icon.h" |
| 12 #include "chrome/browser/status_icons/status_tray.h" | 12 #include "chrome/browser/status_icons/status_tray.h" |
| 13 #include "chrome/browser/ui/views/message_center/notification_bubble_wrapper.h" | |
| 14 #include "content/public/browser/user_metrics.h" | 13 #include "content/public/browser/user_metrics.h" |
| 15 #include "grit/chromium_strings.h" | 14 #include "grit/chromium_strings.h" |
| 16 #include "grit/theme_resources.h" | 15 #include "grit/theme_resources.h" |
| 17 #include "grit/ui_strings.h" | 16 #include "grit/ui_strings.h" |
| 18 #include "ui/base/l10n/l10n_util.h" | 17 #include "ui/base/l10n/l10n_util.h" |
| 19 #include "ui/base/models/simple_menu_model.h" | |
| 20 #include "ui/base/resource/resource_bundle.h" | 18 #include "ui/base/resource/resource_bundle.h" |
| 21 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
| 22 #include "ui/gfx/image/image_skia_operations.h" | 20 #include "ui/gfx/image/image_skia_operations.h" |
| 23 #include "ui/gfx/rect.h" | 21 #include "ui/gfx/rect.h" |
| 24 #include "ui/gfx/screen.h" | 22 #include "ui/gfx/screen.h" |
| 25 #include "ui/gfx/size.h" | 23 #include "ui/gfx/size.h" |
| 26 #include "ui/message_center/message_center_tray.h" | 24 #include "ui/message_center/message_center_tray.h" |
| 27 #include "ui/message_center/message_center_tray_delegate.h" | 25 #include "ui/message_center/message_center_tray_delegate.h" |
| 28 #include "ui/message_center/views/message_bubble_base.h" | |
| 29 #include "ui/message_center/views/message_center_bubble.h" | |
| 30 #include "ui/message_center/views/message_popup_collection.h" | 26 #include "ui/message_center/views/message_popup_collection.h" |
| 31 #include "ui/views/widget/widget.h" | 27 #include "ui/views/widget/widget.h" |
| 32 | 28 |
| 33 namespace { | 29 namespace { |
| 34 | 30 |
| 35 // Tray constants | 31 // Tray constants |
| 36 const int kScreenEdgePadding = 2; | 32 const int kScreenEdgePadding = 2; |
| 37 | 33 |
| 38 const int kSystemTrayWidth = 16; | 34 const int kSystemTrayWidth = 16; |
| 39 const int kSystemTrayHeight = 16; | 35 const int kSystemTrayHeight = 16; |
| 40 const int kNumberOfSystemTraySprites = 10; | 36 const int kNumberOfSystemTraySprites = 10; |
| 41 | 37 |
| 42 gfx::Rect GetCornerAnchorRect() { | 38 gfx::ImageSkia GetIcon(int unread_count) { |
| 43 // TODO(dewittj): Use the preference to determine which corner to anchor from. | 39 bool has_unread = unread_count > 0; |
| 44 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | 40 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 45 gfx::Rect rect = screen->GetPrimaryDisplay().work_area(); | 41 if (!has_unread) |
| 46 rect.Inset(kScreenEdgePadding, kScreenEdgePadding); | 42 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY); |
| 47 return gfx::Rect(rect.bottom_right(), gfx::Size()); | 43 |
| 44 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_ATTENTION); |
| 48 } | 45 } |
| 49 | 46 |
| 50 gfx::Point GetClosestCorner(gfx::Rect rect, gfx::Point query) { | 47 } // namespace |
| 48 |
| 49 using content::UserMetricsAction; |
| 50 |
| 51 namespace message_center { |
| 52 |
| 53 namespace internal { |
| 54 |
| 55 // Gets the position of the taskbar from the work area bounds. Returns |
| 56 // ALIGNMENT_NONE if position cannot be found. |
| 57 Alignment GetTaskbarAlignment() { |
| 58 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); |
| 59 // TODO(dewittj): It's possible GetPrimaryDisplay is wrong. |
| 60 gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds(); |
| 61 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); |
| 62 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding); |
| 63 |
| 64 // Comparing the work area to the screen bounds gives us the location of the |
| 65 // taskbar. If the work area is exactly the same as the screen bounds, |
| 66 // we are unable to locate the taskbar so we say we don't know it's alignment. |
| 67 if (work_area.height() < screen_bounds.height()) { |
| 68 if (work_area.y() > screen_bounds.y()) |
| 69 return ALIGNMENT_TOP; |
| 70 return ALIGNMENT_BOTTOM; |
| 71 } |
| 72 if (work_area.width() < screen_bounds.width()) { |
| 73 if (work_area.x() > screen_bounds.x()) |
| 74 return ALIGNMENT_LEFT; |
| 75 return ALIGNMENT_RIGHT; |
| 76 } |
| 77 |
| 78 return ALIGNMENT_NONE; |
| 79 } |
| 80 |
| 81 gfx::Point GetClosestCorner(const gfx::Rect& rect, const gfx::Point& query) { |
| 51 gfx::Point center_point = rect.CenterPoint(); | 82 gfx::Point center_point = rect.CenterPoint(); |
| 52 gfx::Point rv; | 83 gfx::Point rv; |
| 53 | 84 |
| 54 if (query.x() > center_point.x()) | 85 if (query.x() > center_point.x()) |
| 55 rv.set_x(rect.right()); | 86 rv.set_x(rect.right()); |
| 56 else | 87 else |
| 57 rv.set_x(rect.x()); | 88 rv.set_x(rect.x()); |
| 58 | 89 |
| 59 if (query.y() > center_point.y()) | 90 if (query.y() > center_point.y()) |
| 60 rv.set_y(rect.bottom()); | 91 rv.set_y(rect.bottom()); |
| 61 else | 92 else |
| 62 rv.set_y(rect.y()); | 93 rv.set_y(rect.y()); |
| 63 | 94 |
| 64 return rv; | 95 return rv; |
| 65 } | 96 } |
| 66 | 97 |
| 67 // GetMouseAnchorRect returns a rectangle that has one corner where the mouse | 98 // Gets the corner of the screen where the message center should pop up. |
| 68 // clicked, and the opposite corner at the closest corner of the work area | 99 Alignment GetAnchorAlignment(const gfx::Rect& work_area, gfx::Point corner) { |
| 69 // (inset by an appropriate margin.) | 100 gfx::Point center = work_area.CenterPoint(); |
| 70 gfx::Rect GetMouseAnchorRect(gfx::Point cursor) { | |
| 71 // TODO(dewittj): GetNativeScreen could be wrong for Aura. | |
| 72 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 73 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); | |
| 74 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding); | |
| 75 gfx::Point corner = GetClosestCorner(work_area, cursor); | |
| 76 | 101 |
| 77 gfx::Rect mouse_anchor_rect(gfx::BoundingRect(cursor, corner)); | 102 Alignment anchor_alignment = |
| 78 return mouse_anchor_rect; | 103 center.y() > corner.y() ? ALIGNMENT_TOP : ALIGNMENT_BOTTOM; |
| 104 anchor_alignment = |
| 105 (Alignment)(anchor_alignment | |
| 106 (center.x() > corner.x() ? ALIGNMENT_LEFT : ALIGNMENT_RIGHT)); |
| 107 |
| 108 return anchor_alignment; |
| 79 } | 109 } |
| 80 | 110 |
| 81 gfx::ImageSkia GetIcon(int unread_count) { | 111 } // namespace internal |
| 82 bool has_unread = unread_count > 0; | |
| 83 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 84 if (!has_unread) | |
| 85 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY); | |
| 86 | |
| 87 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_ATTENTION); | |
| 88 } | |
| 89 | |
| 90 } // namespace | |
| 91 | |
| 92 using content::UserMetricsAction; | |
| 93 | |
| 94 namespace message_center { | |
| 95 | 112 |
| 96 MessageCenterTrayDelegate* CreateMessageCenterTray() { | 113 MessageCenterTrayDelegate* CreateMessageCenterTray() { |
| 97 return new WebNotificationTray(); | 114 return new WebNotificationTray(); |
| 98 } | 115 } |
| 99 | 116 |
| 100 WebNotificationTray::WebNotificationTray() | 117 WebNotificationTray::WebNotificationTray() |
| 101 : status_icon_(NULL), | 118 : message_center_delegate_(NULL), |
| 119 status_icon_(NULL), |
| 102 message_center_visible_(false), | 120 message_center_visible_(false), |
| 103 should_update_tray_content_(true) { | 121 should_update_tray_content_(true) { |
| 104 message_center_tray_.reset( | 122 message_center_tray_.reset( |
| 105 new MessageCenterTray(this, g_browser_process->message_center())); | 123 new MessageCenterTray(this, g_browser_process->message_center())); |
| 106 UpdateStatusIcon(); | 124 UpdateStatusIcon(); |
| 107 } | 125 } |
| 108 | 126 |
| 109 WebNotificationTray::~WebNotificationTray() { | 127 WebNotificationTray::~WebNotificationTray() { |
| 110 // Reset this early so that delegated events during destruction don't cause | 128 // Reset this early so that delegated events during destruction don't cause |
| 111 // problems. | 129 // problems. |
| 112 message_center_tray_.reset(); | 130 message_center_tray_.reset(); |
| 113 DestroyStatusIcon(); | 131 DestroyStatusIcon(); |
| 114 } | 132 } |
| 115 | 133 |
| 116 message_center::MessageCenter* WebNotificationTray::message_center() { | 134 message_center::MessageCenter* WebNotificationTray::message_center() { |
| 117 return message_center_tray_->message_center(); | 135 return message_center_tray_->message_center(); |
| 118 } | 136 } |
| 119 | 137 |
| 120 bool WebNotificationTray::ShowPopups() { | 138 bool WebNotificationTray::ShowPopups() { |
| 121 popup_collection_.reset(new message_center::MessagePopupCollection( | 139 popup_collection_.reset(new message_center::MessagePopupCollection( |
| 122 NULL, message_center(), message_center_tray_.get())); | 140 NULL, message_center(), message_center_tray_.get())); |
| 123 return true; | 141 return true; |
| 124 } | 142 } |
| 125 | 143 |
| 126 void WebNotificationTray::HidePopups() { popup_collection_.reset(); } | 144 void WebNotificationTray::HidePopups() { popup_collection_.reset(); } |
| 127 | 145 |
| 128 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { | 146 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { |
| 129 content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter")); | 147 content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter")); |
| 130 | 148 |
| 131 // Using MessageBubbleBase instead of MessageCenterBubble to | 149 // Message center delegate will be set to NULL when the message center |
| 132 // remove dependence on implicit type conversion | 150 // widget's Close method is called so we don't need to worry about |
| 133 scoped_ptr<message_center::MessageCenterBubble> bubble( | 151 // use-after-free issues. |
| 134 new message_center::MessageCenterBubble(message_center(), | 152 message_center_delegate_ = new MessageCenterWidgetDelegate( |
| 135 message_center_tray_.get())); | 153 this, |
| 154 message_center_tray_.get(), |
| 155 show_settings, // settings initally invisible |
| 156 GetPositionInfo()); |
| 136 | 157 |
| 137 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 138 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); | |
| 139 views::TrayBubbleView::AnchorAlignment alignment = GetAnchorAlignment(); | |
| 140 | |
| 141 int max_height = work_area.height(); | |
| 142 | |
| 143 // If the alignment is left- or right-oriented, the bubble can fill up the | |
| 144 // entire vertical height of the screen since the bubble is rendered to the | |
| 145 // side of the clicked icon. Otherwise we have to adjust for the arrow's | |
| 146 // height. | |
| 147 if (alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM || | |
| 148 alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_TOP) { | |
| 149 max_height -= 2 * kScreenEdgePadding; | |
| 150 | |
| 151 // If the work area contains the click point, then we know that the icon is | |
| 152 // not in the taskbar. Then we need to subtract the distance of the click | |
| 153 // point from the edge of the work area so we can see the whole bubble. | |
| 154 if (work_area.Contains(mouse_click_point_)) { | |
| 155 max_height -= std::min(mouse_click_point_.y() - work_area.y(), | |
| 156 work_area.bottom() - mouse_click_point_.y()); | |
| 157 } | |
| 158 } | |
| 159 bubble->SetMaxHeight(max_height); | |
| 160 if (show_settings) | |
| 161 bubble->SetSettingsVisible(); | |
| 162 | |
| 163 message_center_bubble_.reset(new internal::NotificationBubbleWrapper( | |
| 164 this, | |
| 165 bubble.PassAs<message_center::MessageBubbleBase>(), | |
| 166 internal::NotificationBubbleWrapper::BUBBLE_TYPE_MESSAGE_CENTER)); | |
| 167 return true; | 158 return true; |
| 168 } | 159 } |
| 169 | 160 |
| 170 bool WebNotificationTray::ShowMessageCenter() { | 161 bool WebNotificationTray::ShowMessageCenter() { |
| 171 return ShowMessageCenterInternal(false /* show_settings */); | 162 return ShowMessageCenterInternal(/*show_settings =*/false); |
| 172 } | 163 } |
| 173 | 164 |
| 174 void WebNotificationTray::HideMessageCenter() { | 165 void WebNotificationTray::HideMessageCenter() { |
| 175 message_center_bubble_.reset(); | 166 if (message_center_delegate_) { |
| 167 views::Widget* widget = message_center_delegate_->GetWidget(); |
| 168 if (widget) |
| 169 widget->Close(); |
| 170 } |
| 176 } | 171 } |
| 177 | 172 |
| 178 bool WebNotificationTray::ShowNotifierSettings() { | 173 bool WebNotificationTray::ShowNotifierSettings() { |
| 179 if (message_center_bubble_) { | 174 if (message_center_delegate_) { |
| 180 static_cast<MessageCenterBubble*>( | 175 message_center_delegate_->SetSettingsVisible(true); |
| 181 message_center_bubble_->bubble())->SetSettingsVisible(); | |
| 182 return true; | 176 return true; |
| 183 } | 177 } |
| 184 return ShowMessageCenterInternal(true /* show_settings */); | 178 return ShowMessageCenterInternal(/*show_settings =*/true); |
| 185 } | 179 } |
| 186 | 180 |
| 187 void WebNotificationTray::OnMessageCenterTrayChanged() { | 181 void WebNotificationTray::OnMessageCenterTrayChanged() { |
| 188 // See the comments in ash/system/web_notification/web_notification_tray.cc | 182 // See the comments in ash/system/web_notification/web_notification_tray.cc |
| 189 // for why PostTask. | 183 // for why PostTask. |
| 190 should_update_tray_content_ = true; | 184 should_update_tray_content_ = true; |
| 191 base::MessageLoop::current()->PostTask( | 185 base::MessageLoop::current()->PostTask( |
| 192 FROM_HERE, | 186 FROM_HERE, |
| 193 base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr())); | 187 base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr())); |
| 194 } | 188 } |
| 195 | 189 |
| 196 gfx::Rect WebNotificationTray::GetMessageCenterAnchor() { | 190 void WebNotificationTray::OnStatusIconClicked() { |
| 197 return GetMouseAnchorRect(mouse_click_point_); | 191 // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura. |
| 192 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); |
| 193 mouse_click_point_ = screen->GetCursorScreenPoint(); |
| 194 message_center_tray_->ToggleMessageCenterBubble(); |
| 198 } | 195 } |
| 199 | 196 |
| 200 gfx::Rect WebNotificationTray::GetPopupAnchor() { | |
| 201 return GetCornerAnchorRect(); | |
| 202 } | |
| 203 | |
| 204 views::TrayBubbleView::AnchorAlignment | |
| 205 WebNotificationTray::GetAnchorAlignment() { | |
| 206 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 207 // TODO(dewittj): It's possible GetPrimaryDisplay is wrong. | |
| 208 gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds(); | |
| 209 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); | |
| 210 | |
| 211 // Comparing the work area to the screen bounds gives us the location of the | |
| 212 // taskbar. If the work area is less tall than the screen, assume the taskbar | |
| 213 // is on the bottom, and cause the arrow to be displayed on the bottom of the | |
| 214 // bubble. Otherwise, cause the arrow to be displayed on the side of the | |
| 215 // bubble that the taskbar is on. | |
| 216 if (work_area.width() < screen_bounds.width()) { | |
| 217 if (work_area.x() > screen_bounds.x()) | |
| 218 return views::TrayBubbleView::ANCHOR_ALIGNMENT_LEFT; | |
| 219 return views::TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT; | |
| 220 } | |
| 221 return views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM; | |
| 222 } | |
| 223 | |
| 224 gfx::NativeView WebNotificationTray::GetBubbleWindowContainer() { return NULL; } | |
| 225 | |
| 226 void WebNotificationTray::UpdateStatusIcon() { | 197 void WebNotificationTray::UpdateStatusIcon() { |
| 227 if (!should_update_tray_content_) | 198 if (!should_update_tray_content_) |
| 228 return; | 199 return; |
| 229 should_update_tray_content_ = false; | 200 should_update_tray_content_ = false; |
| 230 | 201 |
| 231 int total_notifications = message_center()->NotificationCount(); | 202 int total_notifications = message_center()->NotificationCount(); |
| 232 if (total_notifications == 0) { | 203 if (total_notifications == 0) { |
| 233 DestroyStatusIcon(); | 204 DestroyStatusIcon(); |
| 234 return; | 205 return; |
| 235 } | 206 } |
| 236 | 207 |
| 237 int unread_notifications = message_center()->UnreadNotificationCount(); | 208 int unread_notifications = message_center()->UnreadNotificationCount(); |
| 238 StatusIcon* status_icon = GetStatusIcon(); | 209 StatusIcon* status_icon = GetStatusIcon(); |
| 239 if (!status_icon) | 210 if (!status_icon) |
| 240 return; | 211 return; |
| 241 | 212 |
| 242 status_icon->SetImage(GetIcon(unread_notifications)); | 213 status_icon->SetImage(GetIcon(unread_notifications)); |
| 243 | 214 |
| 244 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); | 215 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); |
| 245 if (unread_notifications > 0) { | 216 if (unread_notifications > 0) { |
| 246 string16 str_unread_count = base::FormatNumber(unread_notifications); | 217 string16 str_unread_count = base::FormatNumber(unread_notifications); |
| 247 status_icon->SetToolTip(l10n_util::GetStringFUTF16( | 218 status_icon->SetToolTip(l10n_util::GetStringFUTF16( |
| 248 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count)); | 219 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count)); |
| 249 } else { | 220 } else { |
| 250 status_icon->SetToolTip( | 221 status_icon->SetToolTip( |
| 251 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP, product_name)); | 222 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP, product_name)); |
| 252 } | 223 } |
| 253 } | 224 } |
| 254 | 225 |
| 255 void WebNotificationTray::OnStatusIconClicked() { | 226 void WebNotificationTray::SendHideMessageCenter() { |
| 256 // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura. | 227 message_center_tray_->HideMessageCenterBubble(); |
| 257 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 258 mouse_click_point_ = screen->GetCursorScreenPoint(); | |
| 259 message_center_tray_->ToggleMessageCenterBubble(); | |
| 260 } | 228 } |
| 261 | 229 |
| 262 void WebNotificationTray::HideBubbleWithView( | 230 void WebNotificationTray::MarkMessageCenterHidden() { |
| 263 const views::TrayBubbleView* bubble_view) { | 231 if (message_center_delegate_) { |
| 264 if (message_center_bubble_.get() && | 232 message_center_tray_->MarkMessageCenterHidden(); |
| 265 bubble_view == message_center_bubble_->bubble_view()) { | 233 message_center_delegate_ = NULL; |
| 266 message_center_tray_->HideMessageCenterBubble(); | |
| 267 } | 234 } |
| 268 } | 235 } |
| 269 | 236 |
| 237 PositionInfo WebNotificationTray::GetPositionInfo() { |
| 238 PositionInfo pos_info; |
| 239 |
| 240 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); |
| 241 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); |
| 242 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding); |
| 243 |
| 244 gfx::Point corner = internal::GetClosestCorner(work_area, mouse_click_point_); |
| 245 |
| 246 pos_info.taskbar_alignment = internal::GetTaskbarAlignment(); |
| 247 |
| 248 // We assume the taskbar is either at the top or at the bottom if we are not |
| 249 // able to find it. |
| 250 if (pos_info.taskbar_alignment == ALIGNMENT_NONE) { |
| 251 if (mouse_click_point_.y() > corner.y()) |
| 252 pos_info.taskbar_alignment = ALIGNMENT_TOP; |
| 253 else |
| 254 pos_info.taskbar_alignment = ALIGNMENT_BOTTOM; |
| 255 } |
| 256 |
| 257 pos_info.message_center_alignment = |
| 258 internal::GetAnchorAlignment(work_area, corner); |
| 259 |
| 260 pos_info.inital_anchor_point = corner; |
| 261 pos_info.max_height = work_area.height(); |
| 262 |
| 263 if (work_area.Contains(mouse_click_point_)) { |
| 264 pos_info.max_height -= std::abs(mouse_click_point_.y() - corner.y()); |
| 265 |
| 266 // Message center is in the work area. So position it few pixels above the |
| 267 // mouse click point if alignemnt is towards bottom and few pixels below if |
| 268 // alignment is towards top. |
| 269 pos_info.inital_anchor_point |
| 270 .set_y(mouse_click_point_.y() + |
| 271 (pos_info.message_center_alignment & ALIGNMENT_BOTTOM ? -5 : 5)); |
| 272 } |
| 273 return pos_info; |
| 274 } |
| 275 |
| 270 StatusIcon* WebNotificationTray::GetStatusIcon() { | 276 StatusIcon* WebNotificationTray::GetStatusIcon() { |
| 271 if (status_icon_) | 277 if (status_icon_) |
| 272 return status_icon_; | 278 return status_icon_; |
| 273 | 279 |
| 274 StatusTray* status_tray = g_browser_process->status_tray(); | 280 StatusTray* status_tray = g_browser_process->status_tray(); |
| 275 if (!status_tray) | 281 if (!status_tray) |
| 276 return NULL; | 282 return NULL; |
| 277 | 283 |
| 278 StatusIcon* status_icon = status_tray->CreateStatusIcon(); | 284 StatusIcon* status_icon = status_tray->CreateStatusIcon(); |
| 279 if (!status_icon) | 285 if (!status_icon) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 295 if (status_tray) | 301 if (status_tray) |
| 296 status_tray->RemoveStatusIcon(status_icon_); | 302 status_tray->RemoveStatusIcon(status_icon_); |
| 297 status_icon_ = NULL; | 303 status_icon_ = NULL; |
| 298 } | 304 } |
| 299 | 305 |
| 300 void WebNotificationTray::AddQuietModeMenu(StatusIcon* status_icon) { | 306 void WebNotificationTray::AddQuietModeMenu(StatusIcon* status_icon) { |
| 301 DCHECK(status_icon); | 307 DCHECK(status_icon); |
| 302 status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu()); | 308 status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu()); |
| 303 } | 309 } |
| 304 | 310 |
| 305 message_center::MessageCenterBubble* | 311 MessageCenterWidgetDelegate* |
| 306 WebNotificationTray::GetMessageCenterBubbleForTest() { | 312 WebNotificationTray::GetMessageCenterWidgetDelegateForTest() { |
| 307 if (!message_center_bubble_.get()) | 313 return message_center_delegate_; |
| 308 return NULL; | |
| 309 return static_cast<message_center::MessageCenterBubble*>( | |
| 310 message_center_bubble_->bubble()); | |
| 311 } | 314 } |
| 312 | 315 |
| 313 } // namespace message_center | 316 } // namespace message_center |
| OLD | NEW |