Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ash/system/web_notification/web_notification_tray.h" | 5 #include "ash/system/web_notification/web_notification_tray.h" |
| 6 | 6 |
| 7 #include "ash/root_window_controller.h" | 7 #include "ash/root_window_controller.h" |
| 8 #include "ash/shelf/shelf_layout_manager.h" | 8 #include "ash/shelf/shelf_layout_manager.h" |
| 9 #include "ash/shell.h" | 9 #include "ash/shell.h" |
| 10 #include "ash/shell_window_ids.h" | 10 #include "ash/shell_window_ids.h" |
| 11 #include "ash/system/status_area_widget.h" | 11 #include "ash/system/status_area_widget.h" |
| 12 #include "ash/system/tray/tray_background_view.h" | 12 #include "ash/system/tray/tray_background_view.h" |
| 13 #include "ash/system/tray/tray_bubble_wrapper.h" | 13 #include "ash/system/tray/tray_bubble_wrapper.h" |
| 14 #include "ash/system/tray/tray_constants.h" | 14 #include "ash/system/tray/tray_constants.h" |
| 15 #include "base/strings/string_number_conversions.h" | |
| 16 #include "base/utf_string_conversions.h" | |
| 15 #include "grit/ash_resources.h" | 17 #include "grit/ash_resources.h" |
| 16 #include "grit/ui_strings.h" | 18 #include "grit/ui_strings.h" |
| 17 #include "ui/aura/root_window.h" | 19 #include "ui/aura/root_window.h" |
| 18 #include "ui/aura/window.h" | 20 #include "ui/aura/window.h" |
| 19 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
| 20 #include "ui/base/resource/resource_bundle.h" | 22 #include "ui/base/resource/resource_bundle.h" |
| 21 #include "ui/gfx/screen.h" | 23 #include "ui/gfx/screen.h" |
| 22 #include "ui/message_center/message_center_tray_delegate.h" | 24 #include "ui/message_center/message_center_tray_delegate.h" |
| 23 #include "ui/message_center/message_center_util.h" | 25 #include "ui/message_center/message_center_util.h" |
| 24 #include "ui/message_center/views/message_bubble_base.h" | 26 #include "ui/message_center/views/message_bubble_base.h" |
| 25 #include "ui/message_center/views/message_center_bubble.h" | 27 #include "ui/message_center/views/message_center_bubble.h" |
| 26 #include "ui/message_center/views/message_popup_bubble.h" | 28 #include "ui/message_center/views/message_popup_bubble.h" |
| 27 #include "ui/message_center/views/message_popup_collection.h" | 29 #include "ui/message_center/views/message_popup_collection.h" |
| 28 #include "ui/views/bubble/tray_bubble_view.h" | 30 #include "ui/views/bubble/tray_bubble_view.h" |
| 29 #include "ui/views/controls/button/image_button.h" | 31 #include "ui/views/controls/button/image_button.h" |
| 32 #include "ui/views/controls/label.h" | |
| 30 #include "ui/views/controls/menu/menu_runner.h" | 33 #include "ui/views/controls/menu/menu_runner.h" |
| 31 | 34 |
| 32 #if defined(OS_CHROMEOS) | 35 #if defined(OS_CHROMEOS) |
| 33 | 36 |
| 34 namespace message_center { | 37 namespace message_center { |
| 35 | 38 |
| 36 MessageCenterTrayDelegate* CreateMessageCenterTray() { | 39 MessageCenterTrayDelegate* CreateMessageCenterTray() { |
| 37 // On Windows+Ash the Tray will not be hosted in ash::Shell. | 40 // On Windows+Ash the Tray will not be hosted in ash::Shell. |
| 38 NOTREACHED(); | 41 NOTREACHED(); |
| 39 return NULL; | 42 return NULL; |
| 40 } | 43 } |
| 41 | 44 |
| 42 } // namespace message_center | 45 } // namespace message_center |
| 43 | 46 |
| 44 #endif // defined(OS_CHROMEOS) | 47 #endif // defined(OS_CHROMEOS) |
| 45 | 48 |
| 46 namespace ash { | 49 namespace ash { |
| 50 namespace internal { | |
| 51 namespace { | |
| 47 | 52 |
| 48 namespace internal { | 53 // The text cannot be placed in the middle of the button vertically. This |
| 54 // constant is used to modify the vertical position of the text. | |
| 55 const int kUnreadLabelBottomOffset = 4; | |
|
dewittj
2013/04/19 21:34:32
Is this the font's descender height? Will we want
Jun Mukai
2013/04/19 22:22:34
No, without this offset, the number is very close
| |
| 56 | |
| 57 } | |
| 49 | 58 |
| 50 // Class to initialize and manage the WebNotificationBubble and | 59 // Class to initialize and manage the WebNotificationBubble and |
| 51 // TrayBubbleWrapper instances for a bubble. | 60 // TrayBubbleWrapper instances for a bubble. |
| 52 | 61 |
| 53 class WebNotificationBubbleWrapper { | 62 class WebNotificationBubbleWrapper { |
| 54 public: | 63 public: |
| 55 // Takes ownership of |bubble| and creates |bubble_wrapper_|. | 64 // Takes ownership of |bubble| and creates |bubble_wrapper_|. |
| 56 WebNotificationBubbleWrapper(WebNotificationTray* tray, | 65 WebNotificationBubbleWrapper(WebNotificationTray* tray, |
| 57 message_center::MessageBubbleBase* bubble) { | 66 message_center::MessageBubbleBase* bubble) { |
| 58 bubble_.reset(bubble); | 67 bubble_.reset(bubble); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 73 } | 82 } |
| 74 | 83 |
| 75 message_center::MessageBubbleBase* bubble() const { return bubble_.get(); } | 84 message_center::MessageBubbleBase* bubble() const { return bubble_.get(); } |
| 76 | 85 |
| 77 // Convenience accessors. | 86 // Convenience accessors. |
| 78 views::TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); } | 87 views::TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); } |
| 79 | 88 |
| 80 private: | 89 private: |
| 81 scoped_ptr<message_center::MessageBubbleBase> bubble_; | 90 scoped_ptr<message_center::MessageBubbleBase> bubble_; |
| 82 scoped_ptr<internal::TrayBubbleWrapper> bubble_wrapper_; | 91 scoped_ptr<internal::TrayBubbleWrapper> bubble_wrapper_; |
| 92 | |
| 93 DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper); | |
| 94 }; | |
| 95 | |
| 96 class WebNotificationButton : public views::ImageButton { | |
| 97 public: | |
| 98 WebNotificationButton(views::ButtonListener* listener) | |
| 99 : views::ImageButton(listener), | |
| 100 unread_label_(NULL) { | |
| 101 } | |
| 102 | |
| 103 void SetUnreadCount(int unread_count) { | |
| 104 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 105 if (unread_count == 0) { | |
| 106 SetImage(views::CustomButton::STATE_NORMAL, rb.GetImageSkiaNamed( | |
| 107 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_NORMAL)); | |
| 108 SetImage(views::CustomButton::STATE_HOVERED, rb.GetImageSkiaNamed( | |
| 109 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_HOVER)); | |
|
stevenjb
2013/04/19 20:56:06
nit:align
Jun Mukai
2013/04/19 22:22:34
Done.
| |
| 110 SetImage(views::CustomButton::STATE_PRESSED, rb.GetImageSkiaNamed( | |
| 111 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_PRESSED)); | |
| 112 | |
| 113 if (unread_label_) { | |
| 114 delete unread_label_; | |
| 115 unread_label_ = NULL; | |
| 116 } | |
| 117 } else { | |
| 118 SetImage(views::CustomButton::STATE_NORMAL, rb.GetImageSkiaNamed( | |
| 119 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_NORMAL)); | |
| 120 SetImage(views::CustomButton::STATE_HOVERED, rb.GetImageSkiaNamed( | |
| 121 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_HOVER)); | |
| 122 SetImage(views::CustomButton::STATE_PRESSED, rb.GetImageSkiaNamed( | |
| 123 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_PRESSED)); | |
| 124 | |
| 125 string16 text((unread_count > 9) ? | |
| 126 UTF8ToUTF16("9+") : base::IntToString16(unread_count)); | |
| 127 if (unread_label_) { | |
| 128 unread_label_->SetText(text); | |
| 129 } else { | |
| 130 unread_label_ = new views::Label(text); | |
| 131 gfx::Font font = unread_label_->font().DeriveFont(0, gfx::Font::BOLD); | |
| 132 unread_label_->SetFont(font); | |
| 133 unread_label_->SetAutoColorReadabilityEnabled(false); | |
| 134 unread_label_->SetEnabledColor(SK_ColorWHITE); | |
| 135 unread_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER); | |
| 136 AddChildView(unread_label_); | |
| 137 } | |
| 138 } | |
| 139 InvalidateLayout(); | |
| 140 SchedulePaint(); | |
| 141 } | |
| 142 | |
| 143 protected: | |
| 144 // Overridden from views::ImageButton: | |
| 145 virtual void Layout() OVERRIDE { | |
| 146 views::ImageButton::Layout(); | |
| 147 if (unread_label_) { | |
| 148 gfx::Rect parent_bounds(bounds()); | |
| 149 parent_bounds.set_height( | |
| 150 parent_bounds.height() - kUnreadLabelBottomOffset); | |
| 151 unread_label_->SetBoundsRect(parent_bounds); | |
| 152 } | |
| 153 } | |
| 154 | |
| 155 private: | |
| 156 views::Label* unread_label_; | |
| 157 | |
| 158 DISALLOW_COPY_AND_ASSIGN(WebNotificationButton); | |
| 83 }; | 159 }; |
| 84 | 160 |
| 85 } // namespace internal | 161 } // namespace internal |
| 86 | 162 |
| 87 WebNotificationTray::WebNotificationTray( | 163 WebNotificationTray::WebNotificationTray( |
| 88 internal::StatusAreaWidget* status_area_widget) | 164 internal::StatusAreaWidget* status_area_widget) |
| 89 : TrayBackgroundView(status_area_widget), | 165 : TrayBackgroundView(status_area_widget), |
| 90 button_(NULL), | 166 button_(NULL), |
| 91 show_message_center_on_unlock_(false) { | 167 show_message_center_on_unlock_(false) { |
| 92 button_ = new views::ImageButton(this); | 168 button_ = new internal::WebNotificationButton(this); |
| 93 button_->set_triggerable_event_flags( | 169 button_->set_triggerable_event_flags( |
| 94 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON); | 170 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON); |
| 95 tray_container()->AddChildView(button_); | 171 tray_container()->AddChildView(button_); |
| 96 SetVisible(false); | 172 SetVisible(false); |
| 97 message_center_tray_.reset(new message_center::MessageCenterTray( | 173 message_center_tray_.reset(new message_center::MessageCenterTray( |
| 98 this, | 174 this, |
| 99 message_center::MessageCenter::Get())); | 175 message_center::MessageCenter::Get())); |
| 100 OnMessageCenterTrayChanged(); | 176 OnMessageCenterTrayChanged(); |
| 101 } | 177 } |
| 102 | 178 |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 HideBubbleWithView(bubble_view); | 446 HideBubbleWithView(bubble_view); |
| 371 } | 447 } |
| 372 | 448 |
| 373 void WebNotificationTray::ButtonPressed(views::Button* sender, | 449 void WebNotificationTray::ButtonPressed(views::Button* sender, |
| 374 const ui::Event& event) { | 450 const ui::Event& event) { |
| 375 DCHECK_EQ(button_, sender); | 451 DCHECK_EQ(button_, sender); |
| 376 PerformAction(event); | 452 PerformAction(event); |
| 377 } | 453 } |
| 378 | 454 |
| 379 void WebNotificationTray::OnMessageCenterTrayChanged() { | 455 void WebNotificationTray::OnMessageCenterTrayChanged() { |
| 380 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 381 message_center::MessageCenter* message_center = | 456 message_center::MessageCenter* message_center = |
| 382 message_center_tray_->message_center(); | 457 message_center_tray_->message_center(); |
| 383 if (message_center->UnreadNotificationCount() > 0) { | 458 button_->SetUnreadCount(message_center->UnreadNotificationCount()); |
| 384 button_->SetImage(views::CustomButton::STATE_NORMAL, rb.GetImageSkiaNamed( | |
| 385 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_NORMAL)); | |
| 386 button_->SetImage(views::CustomButton::STATE_HOVERED, rb.GetImageSkiaNamed( | |
| 387 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_HOVER)); | |
| 388 button_->SetImage(views::CustomButton::STATE_PRESSED, rb.GetImageSkiaNamed( | |
| 389 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_PRESSED)); | |
| 390 } else { | |
| 391 button_->SetImage(views::CustomButton::STATE_NORMAL, rb.GetImageSkiaNamed( | |
| 392 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_NORMAL)); | |
| 393 button_->SetImage(views::CustomButton::STATE_HOVERED, rb.GetImageSkiaNamed( | |
| 394 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_HOVER)); | |
| 395 button_->SetImage(views::CustomButton::STATE_PRESSED, rb.GetImageSkiaNamed( | |
| 396 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_PRESSED)); | |
| 397 } | |
| 398 if (IsMessageCenterBubbleVisible()) | 459 if (IsMessageCenterBubbleVisible()) |
| 399 button_->SetState(views::CustomButton::STATE_PRESSED); | 460 button_->SetState(views::CustomButton::STATE_PRESSED); |
| 400 else | 461 else |
| 401 button_->SetState(views::CustomButton::STATE_NORMAL); | 462 button_->SetState(views::CustomButton::STATE_NORMAL); |
| 402 // Change the visibility of the buttons here when rich notifications are not | 463 // Change the visibility of the buttons here when rich notifications are not |
| 403 // enabled. If rich notifications are enabled, the visibility is changed at | 464 // enabled. If rich notifications are enabled, the visibility is changed at |
| 404 // UpdateAfterLoginStatusChange() since the visibility won't depend on the | 465 // UpdateAfterLoginStatusChange() since the visibility won't depend on the |
| 405 // number of notifications. | 466 // number of notifications. |
| 406 if (!message_center::IsRichNotificationEnabled()) { | 467 if (!message_center::IsRichNotificationEnabled()) { |
| 407 bool is_visible = | 468 bool is_visible = |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 | 503 |
| 443 message_center::MessagePopupBubble* | 504 message_center::MessagePopupBubble* |
| 444 WebNotificationTray::GetPopupBubbleForTest() { | 505 WebNotificationTray::GetPopupBubbleForTest() { |
| 445 if (!popup_bubble()) | 506 if (!popup_bubble()) |
| 446 return NULL; | 507 return NULL; |
| 447 return static_cast<message_center::MessagePopupBubble*>( | 508 return static_cast<message_center::MessagePopupBubble*>( |
| 448 popup_bubble()->bubble()); | 509 popup_bubble()->bubble()); |
| 449 } | 510 } |
| 450 | 511 |
| 451 } // namespace ash | 512 } // namespace ash |
| OLD | NEW |