OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/message_center/message_center_tray.h" |
| 6 |
| 7 #include "base/memory/singleton.h" |
| 8 #include "base/utf_string_conversions.h" |
| 9 #include "ui/message_center/message_center_bubble.h" |
| 10 #include "ui/message_center/message_popup_bubble.h" |
| 11 #include "ui/views/bubble/tray_bubble_view.h" |
| 12 #include "ui/views/widget/widget.h" |
| 13 |
| 14 namespace { |
| 15 |
| 16 // Helper class that owns the MessageBubbleBase and listens to widget closing |
| 17 // events. |
| 18 class WebNotificationBubbleWrapper : public views::WidgetObserver { |
| 19 public: |
| 20 WebNotificationBubbleWrapper( |
| 21 ui::MessageCenterTray* tray, |
| 22 message_center::MessageBubbleBase* bubble, |
| 23 views::TrayBubbleView::InitParams init_params, |
| 24 gfx::NativeWindow bubble_window_container, |
| 25 views::View* anchor_view); |
| 26 virtual ~WebNotificationBubbleWrapper(); |
| 27 // Convenience accessors. |
| 28 message_center::MessageBubbleBase* message_bubble() const { |
| 29 return message_bubble_.get(); |
| 30 } |
| 31 views::TrayBubbleView* bubble_view() const { |
| 32 return message_bubble_->bubble_view(); |
| 33 } |
| 34 bool IsMessageBubbleVisible(); |
| 35 |
| 36 // views::WidgetObserver overrides: |
| 37 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE; |
| 38 |
| 39 private: |
| 40 scoped_ptr<message_center::MessageBubbleBase> message_bubble_; |
| 41 views::TrayBubbleView* bubble_view_; // unowned |
| 42 views::Widget* bubble_widget_; |
| 43 ui::MessageCenterTray* tray_; |
| 44 DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper); |
| 45 }; |
| 46 |
| 47 WebNotificationBubbleWrapper::WebNotificationBubbleWrapper( |
| 48 ui::MessageCenterTray* tray, |
| 49 message_center::MessageBubbleBase* bubble, |
| 50 views::TrayBubbleView::InitParams init_params, |
| 51 gfx::NativeWindow bubble_window_container, |
| 52 views::View* anchor_view) : |
| 53 tray_(tray) { |
| 54 message_bubble_.reset(bubble); |
| 55 |
| 56 init_params.close_on_deactivate = false; |
| 57 init_params.anchor_type = views::TrayBubbleView::ANCHOR_TYPE_TRAY; |
| 58 |
| 59 bubble_view_ = views::TrayBubbleView::Create( |
| 60 bubble_window_container, |
| 61 anchor_view, |
| 62 tray_, |
| 63 &init_params); |
| 64 |
| 65 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_); |
| 66 bubble_widget_->AddObserver(this); |
| 67 bubble_widget_->StackAtTop(); |
| 68 bubble_widget_->SetAlwaysOnTop(true); |
| 69 bubble_widget_->Activate(); |
| 70 |
| 71 bubble_view_->InitializeAndShowBubble(); |
| 72 |
| 73 bubble_view_->set_close_on_deactivate(true); |
| 74 bubble->InitializeContents(bubble_view_); |
| 75 } |
| 76 |
| 77 WebNotificationBubbleWrapper::~WebNotificationBubbleWrapper() { |
| 78 if (bubble_widget_) { |
| 79 bubble_widget_->RemoveObserver(this); |
| 80 bubble_widget_->Close(); |
| 81 } |
| 82 } |
| 83 |
| 84 void WebNotificationBubbleWrapper::OnWidgetClosing( |
| 85 views::Widget* widget) { |
| 86 if (widget == bubble_widget_) { |
| 87 bubble_widget_->RemoveObserver(this); |
| 88 bubble_widget_->Close(); |
| 89 if (bubble_view_) { |
| 90 tray_->HideBubble(bubble_view_); |
| 91 } |
| 92 } |
| 93 } |
| 94 |
| 95 } // namespace |
| 96 |
| 97 namespace ui { |
| 98 |
| 99 MessageCenterTray::MessageCenterTray(MessageCenterTrayHost* host) |
| 100 : host_(host) { |
| 101 message_center_ = new message_center::MessageCenter(); |
| 102 message_center_->AddObserver(this); |
| 103 } |
| 104 |
| 105 MessageCenterTray::~MessageCenterTray() { |
| 106 message_center_->RemoveObserver(this); |
| 107 popup_bubble_.reset(); |
| 108 } |
| 109 |
| 110 void MessageCenterTray::ShowMessageCenterBubble() { |
| 111 if (message_center_bubble_.get()) |
| 112 return; |
| 113 |
| 114 host_->OnShowMessageCenterBubble(); |
| 115 |
| 116 message_center_->SetMessageCenterVisible(true); |
| 117 OnChanged(); |
| 118 HidePopupBubble(); |
| 119 |
| 120 message_center::MessageCenterBubble* bubble = |
| 121 new message_center::MessageCenterBubble(message_center_); |
| 122 // Delegate to the host to find the system-specific anchor alignment, and to |
| 123 // modify the InitParams as necessary. |
| 124 views::TrayBubbleView::AnchorAlignment alignment = |
| 125 host_->GetAnchorAlignment(); |
| 126 views::TrayBubbleView::InitParams init_params = |
| 127 bubble->GetInitParams(alignment); |
| 128 host_->UpdateInitParams(&init_params); |
| 129 message_center_bubble_.reset(new WebNotificationBubbleWrapper( |
| 130 this, |
| 131 bubble, |
| 132 init_params, |
| 133 host_->GetBubbleWindowContainer(), |
| 134 host_->GetAnchorView())); |
| 135 } |
| 136 |
| 137 bool MessageCenterTray::HideMessageCenterBubble() { |
| 138 if (!message_center_bubble_.get()) |
| 139 return false; |
| 140 |
| 141 host_->OnHideMessageCenterBubble(); |
| 142 |
| 143 message_center_bubble_.reset(); |
| 144 message_center_->SetMessageCenterVisible(false); |
| 145 OnChanged(); |
| 146 return true; |
| 147 } |
| 148 |
| 149 void MessageCenterTray::ToggleMessageCenterBubble() { |
| 150 if (message_center_bubble_.get()) { |
| 151 HideMessageCenterBubble(); |
| 152 } else { |
| 153 ShowMessageCenterBubble(); |
| 154 } |
| 155 } |
| 156 |
| 157 void MessageCenterTray::ShowPopupBubble() { |
| 158 if (!host_->CanShowPopups()) |
| 159 return; |
| 160 if (message_center_bubble_) |
| 161 return; |
| 162 |
| 163 OnChanged(); |
| 164 |
| 165 // If there is already a popup bubble, just update it. |
| 166 if (popup_bubble_) { |
| 167 popup_bubble_->message_bubble()->ScheduleUpdate(); |
| 168 return; |
| 169 } |
| 170 if (message_center_->HasPopupNotifications()) { |
| 171 message_center::MessagePopupBubble* bubble = |
| 172 new message_center::MessagePopupBubble(message_center_); |
| 173 views::TrayBubbleView::AnchorAlignment alignment = |
| 174 host_->GetAnchorAlignment(); |
| 175 views::TrayBubbleView::InitParams init_params = |
| 176 bubble->GetInitParams(alignment); |
| 177 host_->UpdateInitParams(&init_params); |
| 178 |
| 179 // Delegate to the host to find the system-specific anchor alignment, and to |
| 180 // modify the InitParams as necessary. |
| 181 popup_bubble_.reset(new WebNotificationBubbleWrapper( |
| 182 this, |
| 183 bubble, |
| 184 init_params, |
| 185 host_->GetBubbleWindowContainer(), |
| 186 host_->GetAnchorView())); |
| 187 bubble->ScheduleUpdate(); |
| 188 } |
| 189 } |
| 190 |
| 191 bool MessageCenterTray::HidePopupBubble() { |
| 192 if (!popup_bubble_.get()) |
| 193 return false; |
| 194 popup_bubble_.reset(); |
| 195 return true; |
| 196 } |
| 197 |
| 198 views::TrayBubbleView* MessageCenterTray::GetPopupBubbleView() { |
| 199 if (popup_bubble_.get()) |
| 200 return popup_bubble_->bubble_view(); |
| 201 return NULL; |
| 202 } |
| 203 |
| 204 views::TrayBubbleView* MessageCenterTray::GetMessageCenterBubbleView() { |
| 205 if (message_center_bubble_.get()) |
| 206 return message_center_bubble_->bubble_view(); |
| 207 return NULL; |
| 208 } |
| 209 |
| 210 void MessageCenterTray::BubbleViewDestroyed() { |
| 211 if (message_center_bubble_.get()) |
| 212 message_center_bubble_->message_bubble()->BubbleViewDestroyed(); |
| 213 if (popup_bubble_.get()) |
| 214 popup_bubble_->message_bubble()->BubbleViewDestroyed(); |
| 215 } |
| 216 |
| 217 void MessageCenterTray::OnMouseEnteredView() { |
| 218 if (popup_bubble_.get()) |
| 219 popup_bubble_->message_bubble()->OnMouseEnteredView(); |
| 220 } |
| 221 |
| 222 void MessageCenterTray::OnMouseExitedView() { |
| 223 if (popup_bubble_.get()) |
| 224 popup_bubble_->message_bubble()->OnMouseExitedView(); |
| 225 } |
| 226 |
| 227 string16 MessageCenterTray::GetAccessibleNameForBubble() { |
| 228 return host_->GetAccessibleNameForBubble(); |
| 229 } |
| 230 |
| 231 gfx::Rect MessageCenterTray::GetAnchorRect(views::Widget* anchor_widget, |
| 232 AnchorType anchor_type, |
| 233 AnchorAlignment anchor_alignment) { |
| 234 return host_->GetAnchorRect(anchor_widget, anchor_type, anchor_alignment); |
| 235 } |
| 236 |
| 237 void MessageCenterTray::HideBubble(const views::TrayBubbleView* bubble_view) { |
| 238 if (message_center_bubble_.get() && |
| 239 bubble_view == message_center_bubble_->bubble_view()) { |
| 240 HideMessageCenterBubble(); |
| 241 } else if (popup_bubble_.get() && |
| 242 bubble_view == popup_bubble_->bubble_view()) { |
| 243 HidePopupBubble(); |
| 244 } |
| 245 } |
| 246 |
| 247 void MessageCenterTray::OnMessageCenterChanged(bool new_notification) { |
| 248 if (message_center_bubble_.get()) { |
| 249 if (message_center_->NotificationCount() == 0) |
| 250 HideMessageCenterBubble(); |
| 251 else |
| 252 message_center_bubble_->message_bubble()->ScheduleUpdate(); |
| 253 } |
| 254 if (popup_bubble_.get()) { |
| 255 if (message_center_->NotificationCount() == 0) |
| 256 HidePopupBubble(); |
| 257 else |
| 258 popup_bubble_->message_bubble()->ScheduleUpdate(); |
| 259 } |
| 260 |
| 261 OnChanged(); |
| 262 if (new_notification) |
| 263 ShowPopupBubble(); |
| 264 } |
| 265 |
| 266 void MessageCenterTray::OnChanged() { |
| 267 host_->OnMessageCenterTrayChanged(); |
| 268 } |
| 269 |
| 270 } // namespace ui |
OLD | NEW |