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 |