Chromium Code Reviews| 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() { | |
| 43 // TODO(dewittj): Use the preference to determine which corner to anchor from. | |
| 44 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 45 gfx::Rect rect = screen->GetPrimaryDisplay().work_area(); | |
| 46 rect.Inset(kScreenEdgePadding, kScreenEdgePadding); | |
| 47 return gfx::Rect(rect.bottom_right(), gfx::Size()); | |
| 48 } | |
| 49 | |
| 50 gfx::Point GetClosestCorner(gfx::Rect rect, gfx::Point query) { | |
| 51 gfx::Point center_point = rect.CenterPoint(); | |
| 52 gfx::Point rv; | |
| 53 | |
| 54 if (query.x() > center_point.x()) | |
| 55 rv.set_x(rect.right()); | |
| 56 else | |
| 57 rv.set_x(rect.x()); | |
| 58 | |
| 59 if (query.y() > center_point.y()) | |
| 60 rv.set_y(rect.bottom()); | |
| 61 else | |
| 62 rv.set_y(rect.y()); | |
| 63 | |
| 64 return rv; | |
| 65 } | |
| 66 | |
| 67 // GetMouseAnchorRect returns a rectangle that has one corner where the mouse | |
| 68 // clicked, and the opposite corner at the closest corner of the work area | |
| 69 // (inset by an appropriate margin.) | |
| 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 | |
| 77 gfx::Rect mouse_anchor_rect(gfx::BoundingRect(cursor, corner)); | |
| 78 return mouse_anchor_rect; | |
| 79 } | |
| 80 | |
| 81 gfx::ImageSkia GetIcon(int unread_count) { | 38 gfx::ImageSkia GetIcon(int unread_count) { |
| 82 bool has_unread = unread_count > 0; | 39 bool has_unread = unread_count > 0; |
| 83 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 40 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 84 if (!has_unread) | 41 if (!has_unread) |
| 85 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY); | 42 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY); |
| 86 | 43 |
| 87 // TODO(dewittj): Use scale factors other than 100P. | 44 // TODO(dewittj): Use scale factors other than 100P. |
| 88 scoped_ptr<gfx::Canvas> canvas( | 45 scoped_ptr<gfx::Canvas> canvas( |
| 89 new gfx::Canvas(gfx::Size(kSystemTrayWidth, kSystemTrayHeight), | 46 new gfx::Canvas(gfx::Size(kSystemTrayWidth, kSystemTrayHeight), |
| 90 ui::SCALE_FACTOR_100P, | 47 ui::SCALE_FACTOR_100P, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 109 false); | 66 false); |
| 110 return gfx::ImageSkia(canvas->ExtractImageRep()); | 67 return gfx::ImageSkia(canvas->ExtractImageRep()); |
| 111 } | 68 } |
| 112 | 69 |
| 113 } // namespace | 70 } // namespace |
| 114 | 71 |
| 115 using content::UserMetricsAction; | 72 using content::UserMetricsAction; |
| 116 | 73 |
| 117 namespace message_center { | 74 namespace message_center { |
| 118 | 75 |
| 76 namespace internal { | |
| 77 | |
| 78 // Gets the position of the systray (same as position of taskbar) from the | |
| 79 // work area bounds. Returns ALIGNMENT_NONE if position cannot be found. | |
| 80 Alignment GetSystrayAlignment() { | |
|
dewittj
2013/07/15 18:38:58
In the future we could use AppBar for this on Wind
| |
| 81 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 82 // TODO(dewittj): It's possible GetPrimaryDisplay is wrong. | |
| 83 gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds(); | |
| 84 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); | |
| 85 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding); | |
| 86 | |
| 87 // Comparing the work area to the screen bounds gives us the location of the | |
| 88 // taskbar. If the work area is exactly the same as the screen bounds, | |
| 89 // we are unable to locate the systray so we say we don't know it's alignment. | |
| 90 if (work_area.height() < screen_bounds.height()) { | |
| 91 if (work_area.y() > screen_bounds.y()) | |
| 92 return ALIGNMENT_TOP; | |
| 93 return ALIGNMENT_BOTTOM; | |
| 94 } | |
| 95 if (work_area.width() < screen_bounds.width()) { | |
| 96 if (work_area.x() > screen_bounds.x()) | |
| 97 return ALIGNMENT_LEFT; | |
| 98 return ALIGNMENT_RIGHT; | |
| 99 } | |
| 100 | |
| 101 return ALIGNMENT_NONE; | |
| 102 } | |
| 103 | |
| 104 gfx::Point GetClosestCorner(const gfx::Rect& rect, const gfx::Point& query) { | |
| 105 gfx::Point center_point = rect.CenterPoint(); | |
| 106 gfx::Point rv; | |
| 107 | |
| 108 if (query.x() > center_point.x()) | |
| 109 rv.set_x(rect.right()); | |
| 110 else | |
| 111 rv.set_x(rect.x()); | |
| 112 | |
| 113 if (query.y() > center_point.y()) | |
| 114 rv.set_y(rect.bottom()); | |
| 115 else | |
| 116 rv.set_y(rect.y()); | |
| 117 | |
| 118 return rv; | |
| 119 } | |
| 120 | |
| 121 // Gets the corner of the screen where the message center should pop up. | |
|
dewittj
2013/07/15 18:38:58
This comment probably belongs on GetClosestCorner?
| |
| 122 Alignment GetAnchorAlignment(const gfx::Rect& work_area, gfx::Point corner) { | |
| 123 gfx::Point center = work_area.CenterPoint(); | |
| 124 | |
| 125 Alignment anchor_alignment = | |
| 126 center.y() > corner.y() ? ALIGNMENT_TOP : ALIGNMENT_BOTTOM; | |
| 127 anchor_alignment = | |
| 128 (Alignment)(anchor_alignment | | |
| 129 (center.x() > corner.x() ? ALIGNMENT_LEFT : ALIGNMENT_RIGHT)); | |
| 130 | |
| 131 return anchor_alignment; | |
| 132 } | |
| 133 | |
| 134 } // namespace internal | |
| 135 | |
| 119 MessageCenterTrayDelegate* CreateMessageCenterTray() { | 136 MessageCenterTrayDelegate* CreateMessageCenterTray() { |
| 120 return new WebNotificationTray(); | 137 return new WebNotificationTray(); |
| 121 } | 138 } |
| 122 | 139 |
| 123 WebNotificationTray::WebNotificationTray() | 140 WebNotificationTray::WebNotificationTray() |
| 124 : status_icon_(NULL), | 141 : message_center_delegate_(NULL), |
| 142 status_icon_(NULL), | |
| 125 message_center_visible_(false), | 143 message_center_visible_(false), |
| 126 should_update_tray_content_(true) { | 144 should_update_tray_content_(true) { |
| 127 message_center_tray_.reset( | 145 message_center_tray_.reset( |
| 128 new MessageCenterTray(this, g_browser_process->message_center())); | 146 new MessageCenterTray(this, g_browser_process->message_center())); |
| 129 UpdateStatusIcon(); | 147 UpdateStatusIcon(); |
| 130 } | 148 } |
| 131 | 149 |
| 132 WebNotificationTray::~WebNotificationTray() { | 150 WebNotificationTray::~WebNotificationTray() { |
| 133 // Reset this early so that delegated events during destruction don't cause | 151 // Reset this early so that delegated events during destruction don't cause |
| 134 // problems. | 152 // problems. |
| 135 message_center_tray_.reset(); | 153 message_center_tray_.reset(); |
| 136 DestroyStatusIcon(); | 154 DestroyStatusIcon(); |
| 137 } | 155 } |
| 138 | 156 |
| 139 message_center::MessageCenter* WebNotificationTray::message_center() { | 157 message_center::MessageCenter* WebNotificationTray::message_center() { |
| 140 return message_center_tray_->message_center(); | 158 return message_center_tray_->message_center(); |
| 141 } | 159 } |
| 142 | 160 |
| 143 bool WebNotificationTray::ShowPopups() { | 161 bool WebNotificationTray::ShowPopups() { |
| 144 popup_collection_.reset(new message_center::MessagePopupCollection( | 162 popup_collection_.reset(new message_center::MessagePopupCollection( |
| 145 NULL, message_center(), message_center_tray_.get())); | 163 NULL, message_center(), message_center_tray_.get())); |
| 146 return true; | 164 return true; |
| 147 } | 165 } |
| 148 | 166 |
| 149 void WebNotificationTray::HidePopups() { popup_collection_.reset(); } | 167 void WebNotificationTray::HidePopups() { popup_collection_.reset(); } |
| 150 | 168 |
| 151 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { | 169 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { |
| 152 content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter")); | 170 content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter")); |
| 153 | 171 |
| 154 // Using MessageBubbleBase instead of MessageCenterBubble to | 172 message_center_delegate_ = new MessageCenterWidgetDelegate( |
| 155 // remove dependence on implicit type conversion | 173 this, |
| 156 scoped_ptr<message_center::MessageCenterBubble> bubble( | 174 message_center_tray_.get(), |
| 157 new message_center::MessageCenterBubble(message_center(), | 175 show_settings, /* settings initally invisible */ |
|
dewittj
2013/07/15 18:38:58
//-style comment here.
| |
| 158 message_center_tray_.get())); | 176 GetPositionInfo()); |
| 159 | 177 |
| 160 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 161 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); | |
| 162 views::TrayBubbleView::AnchorAlignment alignment = GetAnchorAlignment(); | |
| 163 | |
| 164 int max_height = work_area.height(); | |
| 165 | |
| 166 // If the alignment is left- or right-oriented, the bubble can fill up the | |
| 167 // entire vertical height of the screen since the bubble is rendered to the | |
| 168 // side of the clicked icon. Otherwise we have to adjust for the arrow's | |
| 169 // height. | |
| 170 if (alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM || | |
| 171 alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_TOP) { | |
| 172 max_height -= 2 * kScreenEdgePadding; | |
| 173 | |
| 174 // If the work area contains the click point, then we know that the icon is | |
| 175 // not in the taskbar. Then we need to subtract the distance of the click | |
| 176 // point from the edge of the work area so we can see the whole bubble. | |
| 177 if (work_area.Contains(mouse_click_point_)) { | |
| 178 max_height -= std::min(mouse_click_point_.y() - work_area.y(), | |
| 179 work_area.bottom() - mouse_click_point_.y()); | |
| 180 } | |
| 181 } | |
| 182 bubble->SetMaxHeight(max_height); | |
| 183 if (show_settings) | |
| 184 bubble->SetSettingsVisible(); | |
| 185 | |
| 186 message_center_bubble_.reset(new internal::NotificationBubbleWrapper( | |
| 187 this, | |
| 188 bubble.PassAs<message_center::MessageBubbleBase>(), | |
| 189 internal::NotificationBubbleWrapper::BUBBLE_TYPE_MESSAGE_CENTER)); | |
| 190 return true; | 178 return true; |
| 191 } | 179 } |
| 192 | 180 |
| 193 bool WebNotificationTray::ShowMessageCenter() { | 181 bool WebNotificationTray::ShowMessageCenter() { |
| 194 return ShowMessageCenterInternal(false /* show_settings */); | 182 return ShowMessageCenterInternal(false /* show_settings */); |
| 195 } | 183 } |
| 196 | 184 |
| 197 void WebNotificationTray::HideMessageCenter() { | 185 void WebNotificationTray::HideMessageCenter() { |
| 198 message_center_bubble_.reset(); | 186 if (message_center_delegate_) { |
| 187 views::Widget* widget = message_center_delegate_->GetWidget(); | |
| 188 if (widget) | |
| 189 widget->Close(); | |
| 190 } | |
| 199 } | 191 } |
| 200 | 192 |
| 201 bool WebNotificationTray::ShowNotifierSettings() { | 193 bool WebNotificationTray::ShowNotifierSettings() { |
| 202 if (message_center_bubble_) { | 194 if (message_center_delegate_) { |
| 203 static_cast<MessageCenterBubble*>( | 195 message_center_delegate_->SetSettingsVisible(true); |
| 204 message_center_bubble_->bubble())->SetSettingsVisible(); | |
| 205 return true; | 196 return true; |
| 206 } | 197 } |
| 207 return ShowMessageCenterInternal(true /* show_settings */); | 198 return ShowMessageCenterInternal(true /* show_settings */); |
| 208 } | 199 } |
| 209 | 200 |
| 210 void WebNotificationTray::OnMessageCenterTrayChanged() { | 201 void WebNotificationTray::OnMessageCenterTrayChanged() { |
| 211 // See the comments in ash/system/web_notification/web_notification_tray.cc | 202 // See the comments in ash/system/web_notification/web_notification_tray.cc |
| 212 // for why PostTask. | 203 // for why PostTask. |
| 213 should_update_tray_content_ = true; | 204 should_update_tray_content_ = true; |
| 214 base::MessageLoop::current()->PostTask( | 205 base::MessageLoop::current()->PostTask( |
| 215 FROM_HERE, | 206 FROM_HERE, |
| 216 base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr())); | 207 base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr())); |
| 217 } | 208 } |
| 218 | 209 |
| 219 gfx::Rect WebNotificationTray::GetMessageCenterAnchor() { | 210 void WebNotificationTray::OnStatusIconClicked() { |
| 220 return GetMouseAnchorRect(mouse_click_point_); | 211 // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura. |
| 212 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 213 mouse_click_point_ = screen->GetCursorScreenPoint(); | |
| 214 message_center_tray_->ToggleMessageCenterBubble(); | |
| 221 } | 215 } |
| 222 | 216 |
| 223 gfx::Rect WebNotificationTray::GetPopupAnchor() { | |
| 224 return GetCornerAnchorRect(); | |
| 225 } | |
| 226 | |
| 227 views::TrayBubbleView::AnchorAlignment | |
| 228 WebNotificationTray::GetAnchorAlignment() { | |
| 229 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 230 // TODO(dewittj): It's possible GetPrimaryDisplay is wrong. | |
| 231 gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds(); | |
| 232 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); | |
| 233 | |
| 234 // Comparing the work area to the screen bounds gives us the location of the | |
| 235 // taskbar. If the work area is less tall than the screen, assume the taskbar | |
| 236 // is on the bottom, and cause the arrow to be displayed on the bottom of the | |
| 237 // bubble. Otherwise, cause the arrow to be displayed on the side of the | |
| 238 // bubble that the taskbar is on. | |
| 239 if (work_area.width() < screen_bounds.width()) { | |
| 240 if (work_area.x() > screen_bounds.x()) | |
| 241 return views::TrayBubbleView::ANCHOR_ALIGNMENT_LEFT; | |
| 242 return views::TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT; | |
| 243 } | |
| 244 return views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM; | |
| 245 } | |
| 246 | |
| 247 gfx::NativeView WebNotificationTray::GetBubbleWindowContainer() { return NULL; } | |
| 248 | |
| 249 void WebNotificationTray::UpdateStatusIcon() { | 217 void WebNotificationTray::UpdateStatusIcon() { |
| 250 if (!should_update_tray_content_) | 218 if (!should_update_tray_content_) |
| 251 return; | 219 return; |
| 252 should_update_tray_content_ = false; | 220 should_update_tray_content_ = false; |
| 253 | 221 |
| 254 int total_notifications = message_center()->NotificationCount(); | 222 int total_notifications = message_center()->NotificationCount(); |
| 255 if (total_notifications == 0) { | 223 if (total_notifications == 0) { |
| 256 DestroyStatusIcon(); | 224 DestroyStatusIcon(); |
| 257 return; | 225 return; |
| 258 } | 226 } |
| 259 | 227 |
| 260 int unread_notifications = message_center()->UnreadNotificationCount(); | 228 int unread_notifications = message_center()->UnreadNotificationCount(); |
| 261 StatusIcon* status_icon = GetStatusIcon(); | 229 StatusIcon* status_icon = GetStatusIcon(); |
| 262 if (!status_icon) | 230 if (!status_icon) |
| 263 return; | 231 return; |
| 264 | 232 |
| 265 status_icon->SetImage(GetIcon(unread_notifications)); | 233 status_icon->SetImage(GetIcon(unread_notifications)); |
| 266 | 234 |
| 267 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); | 235 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); |
| 268 if (unread_notifications > 0) { | 236 if (unread_notifications > 0) { |
| 269 string16 str_unread_count = base::FormatNumber(unread_notifications); | 237 string16 str_unread_count = base::FormatNumber(unread_notifications); |
| 270 status_icon->SetToolTip(l10n_util::GetStringFUTF16( | 238 status_icon->SetToolTip(l10n_util::GetStringFUTF16( |
| 271 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count)); | 239 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count)); |
| 272 } else { | 240 } else { |
| 273 status_icon->SetToolTip( | 241 status_icon->SetToolTip( |
| 274 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP, product_name)); | 242 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP, product_name)); |
| 275 } | 243 } |
| 276 } | 244 } |
| 277 | 245 |
| 278 void WebNotificationTray::OnStatusIconClicked() { | 246 void WebNotificationTray::HideBubble() { |
| 279 // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura. | 247 message_center_tray_->HideMessageCenterBubble(); |
| 280 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 281 mouse_click_point_ = screen->GetCursorScreenPoint(); | |
| 282 message_center_tray_->ToggleMessageCenterBubble(); | |
| 283 } | 248 } |
| 284 | 249 |
| 285 void WebNotificationTray::HideBubbleWithView( | 250 void WebNotificationTray::SetMessageCenterHidden() { |
| 286 const views::TrayBubbleView* bubble_view) { | 251 if (message_center_delegate_) { |
| 287 if (message_center_bubble_.get() && | 252 message_center_tray_->SetMessageCenterHidden(); |
| 288 bubble_view == message_center_bubble_->bubble_view()) { | 253 message_center_delegate_ = NULL; |
| 289 message_center_tray_->HideMessageCenterBubble(); | |
| 290 } | 254 } |
| 291 } | 255 } |
| 292 | 256 |
| 257 PositionInfo WebNotificationTray::GetPositionInfo() { | |
| 258 PositionInfo pos_info; | |
| 259 | |
| 260 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 261 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); | |
| 262 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding); | |
| 263 | |
| 264 gfx::Point corner = internal::GetClosestCorner(work_area, mouse_click_point_); | |
| 265 | |
| 266 pos_info.systray_alignment = internal::GetSystrayAlignment(); | |
| 267 | |
| 268 // We assume the systray and taskbar are either at the top or at the bottom | |
| 269 // if we are not able to find it. | |
| 270 if (pos_info.systray_alignment == ALIGNMENT_NONE) { | |
| 271 if (mouse_click_point_.y() > corner.y()) | |
| 272 pos_info.systray_alignment = ALIGNMENT_TOP; | |
| 273 else | |
| 274 pos_info.systray_alignment = ALIGNMENT_BOTTOM; | |
| 275 } | |
| 276 | |
| 277 pos_info.message_center_alignment = | |
| 278 internal::GetAnchorAlignment(work_area, corner); | |
| 279 | |
| 280 pos_info.inital_anchor_point = corner; | |
| 281 pos_info.max_height = work_area.height(); | |
| 282 | |
| 283 if (work_area.Contains(mouse_click_point_)) { | |
| 284 pos_info.max_height -= std::abs(mouse_click_point_.y() - corner.y()); | |
| 285 | |
| 286 // Message center is in the work area. So position it few pixels above the | |
| 287 // mouse click point if alignemnt is towards bottom and few pixels below if | |
| 288 // alignment is towards top. | |
| 289 pos_info.inital_anchor_point.set_y(mouse_click_point_.y() + | |
| 290 (pos_info.message_center_alignment & ALIGNMENT_BOTTOM ? -5 : 5)); | |
| 291 } | |
| 292 return pos_info; | |
| 293 } | |
| 294 | |
| 293 StatusIcon* WebNotificationTray::GetStatusIcon() { | 295 StatusIcon* WebNotificationTray::GetStatusIcon() { |
| 294 if (status_icon_) | 296 if (status_icon_) |
| 295 return status_icon_; | 297 return status_icon_; |
| 296 | 298 |
| 297 StatusTray* status_tray = g_browser_process->status_tray(); | 299 StatusTray* status_tray = g_browser_process->status_tray(); |
| 298 if (!status_tray) | 300 if (!status_tray) |
| 299 return NULL; | 301 return NULL; |
| 300 | 302 |
| 301 StatusIcon* status_icon = status_tray->CreateStatusIcon(); | 303 StatusIcon* status_icon = status_tray->CreateStatusIcon(); |
| 302 if (!status_icon) | 304 if (!status_icon) |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 318 if (status_tray) | 320 if (status_tray) |
| 319 status_tray->RemoveStatusIcon(status_icon_); | 321 status_tray->RemoveStatusIcon(status_icon_); |
| 320 status_icon_ = NULL; | 322 status_icon_ = NULL; |
| 321 } | 323 } |
| 322 | 324 |
| 323 void WebNotificationTray::AddQuietModeMenu(StatusIcon* status_icon) { | 325 void WebNotificationTray::AddQuietModeMenu(StatusIcon* status_icon) { |
| 324 DCHECK(status_icon); | 326 DCHECK(status_icon); |
| 325 status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu()); | 327 status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu()); |
| 326 } | 328 } |
| 327 | 329 |
| 328 message_center::MessageCenterBubble* | 330 MessageCenterWidgetDelegate* |
| 329 WebNotificationTray::GetMessageCenterBubbleForTest() { | 331 WebNotificationTray::GetMessageCenterWidgetDelegateForTest() { |
| 330 if (!message_center_bubble_.get()) | 332 return message_center_delegate_; |
| 331 return NULL; | |
| 332 return static_cast<message_center::MessageCenterBubble*>( | |
| 333 message_center_bubble_->bubble()); | |
| 334 } | 333 } |
| 335 | 334 |
| 336 } // namespace message_center | 335 } // namespace message_center |
| OLD | NEW |