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/common/system/web_notification/web_notification_tray.h" | 5 #include "ash/common/system/web_notification/web_notification_tray.h" |
6 | 6 |
7 #include "ash/common/ash_switches.h" | 7 #include "ash/common/ash_switches.h" |
8 #include "ash/common/material_design/material_design_controller.h" | 8 #include "ash/common/material_design/material_design_controller.h" |
9 #include "ash/common/session/session_state_delegate.h" | 9 #include "ash/common/session/session_state_delegate.h" |
10 #include "ash/common/shelf/shelf_constants.h" | 10 #include "ash/common/shelf/shelf_constants.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 } | 55 } |
56 | 56 |
57 } // namespace message_center | 57 } // namespace message_center |
58 | 58 |
59 #endif // defined(OS_CHROMEOS) | 59 #endif // defined(OS_CHROMEOS) |
60 | 60 |
61 namespace ash { | 61 namespace ash { |
62 namespace { | 62 namespace { |
63 | 63 |
64 // Menu commands | 64 // Menu commands |
65 constexpr int kToggleQuietMode = 0; | 65 const int kToggleQuietMode = 0; |
66 constexpr int kEnableQuietModeDay = 2; | 66 const int kEnableQuietModeDay = 2; |
67 | |
68 constexpr int kMaximumSmallIconCount = 3; | |
69 | |
70 constexpr gfx::Size kTrayItemInnerIconSize(16, 16); | |
71 constexpr gfx::Size kTrayItemInnerBellIconSize(18, 18); | |
72 constexpr gfx::Size kTrayItemOuterSize(26, 26); | |
73 constexpr gfx::Insets kTrayItemInsets(3, 3); | |
74 | |
75 constexpr int kTrayItemAnimationDurationMS = 200; | |
76 | |
77 constexpr size_t kMaximumNotificationNumber = 99; | |
78 | |
79 // Flag to disable animation. Only for testing. | |
80 bool disable_animations_for_test = false; | |
81 } | 67 } |
82 | 68 |
83 namespace { | 69 namespace { |
84 | 70 |
85 const SkColor kWebNotificationColorNoUnread = | 71 const SkColor kWebNotificationColorNoUnread = |
86 SkColorSetARGB(128, 255, 255, 255); | 72 SkColorSetARGB(128, 255, 255, 255); |
87 const SkColor kWebNotificationColorWithUnread = SK_ColorWHITE; | 73 const SkColor kWebNotificationColorWithUnread = SK_ColorWHITE; |
88 const int kNoUnreadIconSize = 18; | 74 const int kNoUnreadIconSize = 18; |
89 } | 75 } |
90 | 76 |
(...skipping 30 matching lines...) Expand all Loading... |
121 // Convenience accessors. | 107 // Convenience accessors. |
122 views::TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); } | 108 views::TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); } |
123 | 109 |
124 private: | 110 private: |
125 std::unique_ptr<message_center::MessageBubbleBase> bubble_; | 111 std::unique_ptr<message_center::MessageBubbleBase> bubble_; |
126 std::unique_ptr<TrayBubbleWrapper> bubble_wrapper_; | 112 std::unique_ptr<TrayBubbleWrapper> bubble_wrapper_; |
127 | 113 |
128 DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper); | 114 DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper); |
129 }; | 115 }; |
130 | 116 |
131 class WebNotificationItem : public views::View, public gfx::AnimationDelegate { | 117 class WebNotificationIcon : public views::View { |
132 public: | 118 public: |
133 WebNotificationItem(gfx::AnimationContainer* container, | 119 WebNotificationIcon() : is_bubble_visible_(false), unread_count_(0) { |
134 WebNotificationTray* tray) | |
135 : tray_(tray) { | |
136 SetPaintToLayer(true); | |
137 layer()->SetFillsBoundsOpaquely(false); | |
138 views::View::SetVisible(false); | |
139 set_owned_by_client(); | |
140 | |
141 SetLayoutManager(new views::FillLayout); | 120 SetLayoutManager(new views::FillLayout); |
142 | 121 |
143 animation_.reset(new gfx::SlideAnimation(this)); | 122 gfx::ImageSkia image; |
144 animation_->SetContainer(container); | 123 if (MaterialDesignController::IsShelfMaterial()) { |
145 animation_->SetSlideDuration(kTrayItemAnimationDurationMS); | 124 image = CreateVectorIcon(gfx::VectorIconId::SHELF_NOTIFICATIONS, |
146 animation_->SetTweenType(gfx::Tween::LINEAR); | 125 kShelfIconColor); |
| 126 } else { |
| 127 image = |
| 128 CreateVectorIcon(gfx::VectorIconId::NOTIFICATIONS, kNoUnreadIconSize, |
| 129 kWebNotificationColorNoUnread); |
| 130 } |
| 131 |
| 132 no_unread_icon_.SetImage(image); |
| 133 no_unread_icon_.set_owned_by_client(); |
| 134 |
| 135 unread_label_.set_owned_by_client(); |
| 136 SetupLabelForTray(&unread_label_); |
| 137 |
| 138 AddChildView(&no_unread_icon_); |
147 } | 139 } |
148 | 140 |
149 void SetVisible(bool set_visible) override { | 141 void SetBubbleVisible(bool visible) { |
150 if (!GetWidget() || disable_animations_for_test) { | 142 if (visible == is_bubble_visible_) |
151 views::View::SetVisible(set_visible); | |
152 return; | 143 return; |
153 } | |
154 | 144 |
155 if (!set_visible) { | 145 is_bubble_visible_ = visible; |
156 animation_->Hide(); | 146 UpdateIconVisibility(); |
157 AnimationProgressed(animation_.get()); | |
158 } else { | |
159 animation_->Show(); | |
160 AnimationProgressed(animation_.get()); | |
161 views::View::SetVisible(true); | |
162 } | |
163 } | 147 } |
164 | 148 |
165 void HideAndDelete() { | 149 void SetUnreadCount(int unread_count) { |
166 SetVisible(false); | 150 // base::FormatNumber doesn't convert to arabic numeric characters. |
167 | 151 // TODO(mukai): use ICU to support conversion for such locales. |
168 if (!visible() && !animation_->is_animating()) { | 152 unread_count_ = unread_count; |
169 if (parent()) | 153 UpdateIconVisibility(); |
170 parent()->RemoveChildView(this); | |
171 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); | |
172 } else { | |
173 delete_after_animation_ = true; | |
174 } | |
175 } | 154 } |
176 | 155 |
177 protected: | 156 protected: |
178 // Overridden from views::View: | 157 // Overridden from views::View: |
179 gfx::Size GetPreferredSize() const override { | 158 gfx::Size GetPreferredSize() const override { |
180 if (!animation_.get() || !animation_->is_animating()) | 159 const int size = GetTrayConstant(TRAY_ITEM_HEIGHT_LEGACY); |
181 return kTrayItemOuterSize; | 160 return gfx::Size(size, size); |
182 | |
183 // Animate the width (or height) when this item shows (or hides) so that | |
184 // the icons on the left are shifted with the animation. | |
185 // Note that TrayItemView does the same thing. | |
186 gfx::Size size = kTrayItemOuterSize; | |
187 if (IsHorizontalLayout()) { | |
188 size.set_width(std::max( | |
189 1, gfx::ToRoundedInt(size.width() * animation_->GetCurrentValue()))); | |
190 } else { | |
191 size.set_height(std::max( | |
192 1, gfx::ToRoundedInt(size.height() * animation_->GetCurrentValue()))); | |
193 } | |
194 return size; | |
195 } | 161 } |
196 | 162 |
197 int GetHeightForWidth(int width) const override { | 163 int GetHeightForWidth(int width) const override { |
198 return GetPreferredSize().height(); | 164 return GetPreferredSize().height(); |
199 } | 165 } |
200 | 166 |
201 bool IsHorizontalLayout() const { | 167 private: |
202 return IsHorizontalAlignment(tray_->shelf_alignment()); | 168 void UpdateIconVisibility() { |
203 } | 169 if (unread_count_ == 0) { |
| 170 if (!Contains(&no_unread_icon_)) { |
| 171 RemoveAllChildViews(false /* delete_children */); |
| 172 AddChildView(&no_unread_icon_); |
| 173 } |
| 174 } else { |
| 175 if (!Contains(&unread_label_)) { |
| 176 RemoveAllChildViews(false /* delete_children */); |
| 177 AddChildView(&unread_label_); |
| 178 } |
204 | 179 |
205 private: | 180 // TODO(mukai): move NINE_PLUS message to ui_strings, it doesn't need to |
206 // gfx::AnimationDelegate: | 181 // be in ash_strings. |
207 void AnimationProgressed(const gfx::Animation* animation) override { | 182 unread_label_.SetText( |
208 gfx::Transform transform; | 183 (unread_count_ > 9) ? l10n_util::GetStringUTF16( |
209 if (IsHorizontalLayout()) { | 184 IDS_ASH_NOTIFICATION_UNREAD_COUNT_NINE_PLUS) |
210 transform.Translate(0, animation->CurrentValueBetween( | 185 : base::FormatNumber(unread_count_)); |
211 static_cast<double>(height()) / 2., 0.)); | 186 unread_label_.SetEnabledColor((unread_count_ > 0) |
212 } else { | 187 ? kWebNotificationColorWithUnread |
213 transform.Translate( | 188 : kWebNotificationColorNoUnread); |
214 animation->CurrentValueBetween(static_cast<double>(width() / 2.), 0.), | |
215 0); | |
216 } | 189 } |
217 transform.Scale(animation->GetCurrentValue(), animation->GetCurrentValue()); | |
218 layer()->SetTransform(transform); | |
219 PreferredSizeChanged(); | |
220 } | |
221 void AnimationEnded(const gfx::Animation* animation) override { | |
222 if (animation->GetCurrentValue() < 0.1) | |
223 views::View::SetVisible(false); | |
224 | |
225 if (delete_after_animation_) { | |
226 if (parent()) | |
227 parent()->RemoveChildView(this); | |
228 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); | |
229 } | |
230 } | |
231 void AnimationCanceled(const gfx::Animation* animation) override { | |
232 AnimationEnded(animation); | |
233 } | |
234 | |
235 std::unique_ptr<gfx::SlideAnimation> animation_; | |
236 bool delete_after_animation_ = false; | |
237 WebNotificationTray* tray_; | |
238 | |
239 DISALLOW_COPY_AND_ASSIGN(WebNotificationItem); | |
240 }; | |
241 | |
242 class WebNotificationImage : public WebNotificationItem { | |
243 public: | |
244 WebNotificationImage(const gfx::ImageSkia& image, | |
245 gfx::Size size, | |
246 gfx::AnimationContainer* container, | |
247 WebNotificationTray* tray) | |
248 : WebNotificationItem(container, tray) { | |
249 view_ = new views::ImageView(); | |
250 view_->SetImage(image); | |
251 view_->SetImageSize(size); | |
252 AddChildView(view_); | |
253 } | |
254 | |
255 private: | |
256 views::ImageView* view_; | |
257 | |
258 DISALLOW_COPY_AND_ASSIGN(WebNotificationImage); | |
259 }; | |
260 | |
261 class WebNotificationLabel : public WebNotificationItem { | |
262 public: | |
263 WebNotificationLabel(gfx::AnimationContainer* container, | |
264 WebNotificationTray* tray) | |
265 : WebNotificationItem(container, tray) { | |
266 view_ = new views::Label(); | |
267 SetupLabelForTray(view_); | |
268 } | |
269 | |
270 void SetNotificationCount(bool small_icons_exist, size_t notification_count) { | |
271 notification_count = std::min(notification_count, | |
272 kMaximumNotificationNumber); // cap with 99 | |
273 | |
274 // TODO(yoshiki): Use a string for "99" and "+99". | |
275 | |
276 base::string16 str = base::FormatNumber(notification_count); | |
277 if (small_icons_exist) { | |
278 if (!base::i18n::IsRTL()) | |
279 str = base::ASCIIToUTF16("+") + str; | |
280 else | |
281 str = str + base::ASCIIToUTF16("+"); | |
282 } | |
283 | |
284 view_->SetText(str); | |
285 view_->SetEnabledColor(kWebNotificationColorWithUnread); | |
286 AddChildView(view_); | |
287 SchedulePaint(); | 190 SchedulePaint(); |
288 } | 191 } |
289 | 192 |
290 private: | 193 bool is_bubble_visible_; |
291 views::Label* view_; | 194 int unread_count_; |
292 | 195 |
293 DISALLOW_COPY_AND_ASSIGN(WebNotificationLabel); | 196 views::ImageView no_unread_icon_; |
| 197 views::Label unread_label_; |
| 198 |
| 199 DISALLOW_COPY_AND_ASSIGN(WebNotificationIcon); |
294 }; | 200 }; |
295 | 201 |
296 WebNotificationTray::WebNotificationTray(WmShelf* shelf, | 202 WebNotificationTray::WebNotificationTray(WmShelf* shelf, |
297 WmWindow* status_area_window, | 203 WmWindow* status_area_window, |
298 SystemTray* system_tray) | 204 SystemTray* system_tray) |
299 : TrayBackgroundView(shelf), | 205 : TrayBackgroundView(shelf), |
300 status_area_window_(status_area_window), | 206 status_area_window_(status_area_window), |
301 system_tray_(system_tray), | 207 system_tray_(system_tray), |
| 208 icon_(new WebNotificationIcon), |
302 show_message_center_on_unlock_(false), | 209 show_message_center_on_unlock_(false), |
303 should_update_tray_content_(false), | 210 should_update_tray_content_(false), |
304 should_block_shelf_auto_hide_(false) { | 211 should_block_shelf_auto_hide_(false) { |
305 DCHECK(shelf); | 212 DCHECK(shelf); |
306 DCHECK(status_area_window_); | 213 DCHECK(status_area_window_); |
307 DCHECK(system_tray_); | 214 DCHECK(system_tray_); |
308 | 215 |
309 gfx::ImageSkia bell_image; | 216 tray_container()->AddChildView(icon_); |
310 if (MaterialDesignController::IsShelfMaterial()) { | |
311 bell_image = CreateVectorIcon(gfx::VectorIconId::SHELF_NOTIFICATIONS, | |
312 kShelfIconColor); | |
313 } else { | |
314 bell_image = | |
315 CreateVectorIcon(gfx::VectorIconId::NOTIFICATIONS, kNoUnreadIconSize, | |
316 kWebNotificationColorNoUnread); | |
317 } | |
318 bell_icon_.reset(new WebNotificationImage(bell_image, | |
319 kTrayItemInnerBellIconSize, | |
320 animation_container_.get(), this)); | |
321 tray_container()->AddChildView(bell_icon_.get()); | |
322 | |
323 counter_.reset(new WebNotificationLabel(animation_container_.get(), this)); | |
324 tray_container()->AddChildView(counter_.get()); | |
325 | |
326 SetContentsBackground(); | 217 SetContentsBackground(); |
327 tray_container()->SetBorder(views::Border::NullBorder()); | 218 tray_container()->SetBorder(views::Border::NullBorder()); |
328 message_center_tray_.reset(new message_center::MessageCenterTray( | 219 message_center_tray_.reset(new message_center::MessageCenterTray( |
329 this, message_center::MessageCenter::Get())); | 220 this, message_center::MessageCenter::Get())); |
330 popup_alignment_delegate_.reset(new AshPopupAlignmentDelegate(shelf)); | 221 popup_alignment_delegate_.reset(new AshPopupAlignmentDelegate(shelf)); |
331 popup_collection_.reset(new message_center::MessagePopupCollection( | 222 popup_collection_.reset(new message_center::MessagePopupCollection( |
332 message_center(), message_center_tray_.get(), | 223 message_center(), message_center_tray_.get(), |
333 popup_alignment_delegate_.get())); | 224 popup_alignment_delegate_.get())); |
334 const display::Display& display = | 225 const display::Display& display = |
335 status_area_window_->GetDisplayNearestWindow(); | 226 status_area_window_->GetDisplayNearestWindow(); |
336 popup_alignment_delegate_->StartObserving(display::Screen::GetScreen(), | 227 popup_alignment_delegate_->StartObserving(display::Screen::GetScreen(), |
337 display); | 228 display); |
338 OnMessageCenterTrayChanged(); | 229 OnMessageCenterTrayChanged(); |
339 | |
340 tray_container()->SetMargin(kTrayItemInsets); | |
341 } | 230 } |
342 | 231 |
343 WebNotificationTray::~WebNotificationTray() { | 232 WebNotificationTray::~WebNotificationTray() { |
344 // Release any child views that might have back pointers before ~View(). | 233 // Release any child views that might have back pointers before ~View(). |
345 message_center_bubble_.reset(); | 234 message_center_bubble_.reset(); |
346 popup_alignment_delegate_.reset(); | 235 popup_alignment_delegate_.reset(); |
347 popup_collection_.reset(); | 236 popup_collection_.reset(); |
348 } | 237 } |
349 | 238 |
350 // static | |
351 void WebNotificationTray::DisableAnimationsForTest(bool disable) { | |
352 disable_animations_for_test = disable; | |
353 } | |
354 | |
355 // Public methods. | 239 // Public methods. |
356 | 240 |
357 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { | 241 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { |
358 if (!ShouldShowMessageCenter()) | 242 if (!ShouldShowMessageCenter()) |
359 return false; | 243 return false; |
360 | 244 |
361 should_block_shelf_auto_hide_ = true; | 245 should_block_shelf_auto_hide_ = true; |
362 message_center::MessageCenterBubble* message_center_bubble = | 246 message_center::MessageCenterBubble* message_center_bubble = |
363 new message_center::MessageCenterBubble(message_center(), | 247 new message_center::MessageCenterBubble(message_center(), |
364 message_center_tray_.get(), true); | 248 message_center_tray_.get(), true); |
365 | 249 |
366 int max_height; | 250 int max_height; |
367 if (IsHorizontalAlignment(shelf_alignment())) { | 251 if (IsHorizontalAlignment(shelf()->GetAlignment())) { |
368 max_height = shelf()->GetIdealBounds().y(); | 252 max_height = shelf()->GetIdealBounds().y(); |
369 } else { | 253 } else { |
370 // Assume the status area and bubble bottoms are aligned when vertical. | 254 // Assume the status area and bubble bottoms are aligned when vertical. |
371 gfx::Rect bounds_in_root = | 255 gfx::Rect bounds_in_root = |
372 status_area_window_->GetRootWindow()->ConvertRectFromScreen( | 256 status_area_window_->GetRootWindow()->ConvertRectFromScreen( |
373 status_area_window_->GetBoundsInScreen()); | 257 status_area_window_->GetBoundsInScreen()); |
374 max_height = bounds_in_root.bottom(); | 258 max_height = bounds_in_root.bottom(); |
375 } | 259 } |
376 message_center_bubble->SetMaxHeight( | 260 message_center_bubble->SetMaxHeight( |
377 std::max(0, max_height - GetTrayConstant(TRAY_SPACING))); | 261 std::max(0, max_height - GetTrayConstant(TRAY_SPACING))); |
378 if (show_settings) | 262 if (show_settings) |
379 message_center_bubble->SetSettingsVisible(); | 263 message_center_bubble->SetSettingsVisible(); |
380 message_center_bubble_.reset( | 264 message_center_bubble_.reset( |
381 new WebNotificationBubbleWrapper(this, message_center_bubble)); | 265 new WebNotificationBubbleWrapper(this, message_center_bubble)); |
382 | 266 |
383 system_tray_->SetHideNotifications(true); | 267 system_tray_->SetHideNotifications(true); |
384 shelf()->UpdateAutoHideState(); | 268 shelf()->UpdateAutoHideState(); |
| 269 icon_->SetBubbleVisible(true); |
385 SetDrawBackgroundAsActive(true); | 270 SetDrawBackgroundAsActive(true); |
386 return true; | 271 return true; |
387 } | 272 } |
388 | 273 |
389 bool WebNotificationTray::ShowMessageCenter() { | 274 bool WebNotificationTray::ShowMessageCenter() { |
390 return ShowMessageCenterInternal(false /* show_settings */); | 275 return ShowMessageCenterInternal(false /* show_settings */); |
391 } | 276 } |
392 | 277 |
393 void WebNotificationTray::HideMessageCenter() { | 278 void WebNotificationTray::HideMessageCenter() { |
394 if (!message_center_bubble()) | 279 if (!message_center_bubble()) |
395 return; | 280 return; |
396 SetDrawBackgroundAsActive(false); | 281 SetDrawBackgroundAsActive(false); |
397 message_center_bubble_.reset(); | 282 message_center_bubble_.reset(); |
398 should_block_shelf_auto_hide_ = false; | 283 should_block_shelf_auto_hide_ = false; |
399 show_message_center_on_unlock_ = false; | 284 show_message_center_on_unlock_ = false; |
400 system_tray_->SetHideNotifications(false); | 285 system_tray_->SetHideNotifications(false); |
401 shelf()->UpdateAutoHideState(); | 286 shelf()->UpdateAutoHideState(); |
| 287 icon_->SetBubbleVisible(false); |
402 } | 288 } |
403 | 289 |
404 void WebNotificationTray::SetTrayBubbleHeight(int height) { | 290 void WebNotificationTray::SetTrayBubbleHeight(int height) { |
405 popup_alignment_delegate_->SetTrayBubbleHeight(height); | 291 popup_alignment_delegate_->SetTrayBubbleHeight(height); |
406 } | 292 } |
407 | 293 |
408 int WebNotificationTray::tray_bubble_height_for_test() const { | 294 int WebNotificationTray::tray_bubble_height_for_test() const { |
409 return popup_alignment_delegate_->tray_bubble_height_for_test(); | 295 return popup_alignment_delegate_->tray_bubble_height_for_test(); |
410 } | 296 } |
411 | 297 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 base::ThreadTaskRunnerHandle::Get()->PostTask( | 463 base::ThreadTaskRunnerHandle::Get()->PostTask( |
578 FROM_HERE, | 464 FROM_HERE, |
579 base::Bind(&WebNotificationTray::UpdateTrayContent, AsWeakPtr())); | 465 base::Bind(&WebNotificationTray::UpdateTrayContent, AsWeakPtr())); |
580 } | 466 } |
581 | 467 |
582 void WebNotificationTray::UpdateTrayContent() { | 468 void WebNotificationTray::UpdateTrayContent() { |
583 if (!should_update_tray_content_) | 469 if (!should_update_tray_content_) |
584 return; | 470 return; |
585 should_update_tray_content_ = false; | 471 should_update_tray_content_ = false; |
586 | 472 |
587 std::unordered_set<std::string> notification_ids; | |
588 for (auto pair : visible_small_icons_) | |
589 notification_ids.insert(pair.first); | |
590 | |
591 // Add small icons (up to kMaximumSmallIconCount = 3). | |
592 message_center::MessageCenter* message_center = | 473 message_center::MessageCenter* message_center = |
593 message_center_tray_->message_center(); | 474 message_center_tray_->message_center(); |
594 size_t visible_small_icon_count = 0; | 475 icon_->SetUnreadCount(message_center->UnreadNotificationCount()); |
595 for (const auto* notification : message_center->GetVisibleNotifications()) { | |
596 gfx::Image image = notification->small_image(); | |
597 if (image.IsEmpty()) | |
598 continue; | |
599 | |
600 if (visible_small_icon_count >= kMaximumSmallIconCount) | |
601 break; | |
602 visible_small_icon_count++; | |
603 | |
604 notification_ids.erase(notification->id()); | |
605 if (visible_small_icons_.count(notification->id()) != 0) | |
606 continue; | |
607 | |
608 auto* item = | |
609 new WebNotificationImage(image.AsImageSkia(), kTrayItemInnerIconSize, | |
610 animation_container_.get(), this); | |
611 visible_small_icons_.insert(std::make_pair(notification->id(), item)); | |
612 | |
613 tray_container()->AddChildViewAt(item, 0); | |
614 item->SetVisible(true); | |
615 } | |
616 | |
617 // Remove unnecessary icons. | |
618 for (const std::string& id : notification_ids) { | |
619 WebNotificationImage* item = visible_small_icons_[id]; | |
620 visible_small_icons_.erase(id); | |
621 item->HideAndDelete(); | |
622 } | |
623 | |
624 // Show or hide the bell icon. | |
625 size_t visible_notification_count = message_center->NotificationCount(); | |
626 bell_icon_->SetVisible(visible_notification_count == 0); | |
627 | |
628 // Show or hide the counter. | |
629 size_t hidden_icon_count = | |
630 visible_notification_count - visible_small_icon_count; | |
631 if (hidden_icon_count != 0) { | |
632 counter_->SetVisible(true); | |
633 counter_->SetNotificationCount( | |
634 (visible_small_icon_count != 0), // small_icons_exist | |
635 hidden_icon_count); | |
636 } else { | |
637 counter_->SetVisible(false); | |
638 } | |
639 | 476 |
640 SetVisible(IsLoggedIn()); | 477 SetVisible(IsLoggedIn()); |
641 PreferredSizeChanged(); | |
642 Layout(); | 478 Layout(); |
643 SchedulePaint(); | 479 SchedulePaint(); |
644 if (IsLoggedIn()) | 480 if (IsLoggedIn()) |
645 system_tray_->SetNextFocusableView(this); | 481 system_tray_->SetNextFocusableView(this); |
646 } | 482 } |
647 | 483 |
648 void WebNotificationTray::ClickedOutsideBubble() { | 484 void WebNotificationTray::ClickedOutsideBubble() { |
649 // Only hide the message center | 485 // Only hide the message center |
650 if (!message_center_bubble()) | 486 if (!message_center_bubble()) |
651 return; | 487 return; |
(...skipping 20 matching lines...) Expand all Loading... |
672 | 508 |
673 message_center::MessageCenterBubble* | 509 message_center::MessageCenterBubble* |
674 WebNotificationTray::GetMessageCenterBubbleForTest() { | 510 WebNotificationTray::GetMessageCenterBubbleForTest() { |
675 if (!message_center_bubble()) | 511 if (!message_center_bubble()) |
676 return NULL; | 512 return NULL; |
677 return static_cast<message_center::MessageCenterBubble*>( | 513 return static_cast<message_center::MessageCenterBubble*>( |
678 message_center_bubble()->bubble()); | 514 message_center_bubble()->bubble()); |
679 } | 515 } |
680 | 516 |
681 } // namespace ash | 517 } // namespace ash |
OLD | NEW |