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/tray/system_tray.h" | 5 #include "ash/system/tray/system_tray.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "ash/shell/panel_window.h" | 8 #include "ash/shell/panel_window.h" |
9 #include "ash/shell_window_ids.h" | 9 #include "ash/shell_window_ids.h" |
10 #include "ash/system/audio/tray_volume.h" | 10 #include "ash/system/audio/tray_volume.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 ime_observer_(NULL), | 170 ime_observer_(NULL), |
171 locale_observer_(NULL), | 171 locale_observer_(NULL), |
172 network_observer_(NULL), | 172 network_observer_(NULL), |
173 power_status_observer_(NULL), | 173 power_status_observer_(NULL), |
174 update_observer_(NULL), | 174 update_observer_(NULL), |
175 user_observer_(NULL), | 175 user_observer_(NULL), |
176 widget_(NULL), | 176 widget_(NULL), |
177 background_(new internal::SystemTrayBackground), | 177 background_(new internal::SystemTrayBackground), |
178 should_show_launcher_(false), | 178 should_show_launcher_(false), |
179 shelf_alignment_(SHELF_ALIGNMENT_BOTTOM), | 179 shelf_alignment_(SHELF_ALIGNMENT_BOTTOM), |
180 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this, | 180 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_( |
181 0, kTrayBackgroundAlpha)), | 181 this, 0, kTrayBackgroundAlpha)), |
182 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this, | 182 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_( |
183 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) { | 183 this, 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)), |
| 184 default_bubble_height_(0) { |
184 tray_container_ = new internal::SystemTrayContainer; | 185 tray_container_ = new internal::SystemTrayContainer; |
185 tray_container_->SetLayoutManager(new views::BoxLayout( | 186 tray_container_->SetLayoutManager(new views::BoxLayout( |
186 views::BoxLayout::kHorizontal, 0, 0, 0)); | 187 views::BoxLayout::kHorizontal, 0, 0, 0)); |
187 tray_container_->set_background(background_); | 188 tray_container_->set_background(background_); |
188 tray_container_->set_border( | 189 tray_container_->set_border( |
189 views::Border::CreateEmptyBorder(1, 1, 1, 1)); | 190 views::Border::CreateEmptyBorder(1, 1, 1, 1)); |
190 set_border(views::Border::CreateEmptyBorder(0, 0, | 191 set_border(views::Border::CreateEmptyBorder(0, 0, |
191 kPaddingFromBottomOfScreenBottomAlignment, | 192 kPaddingFromBottomOfScreenBottomAlignment, |
192 kPaddingFromRightEdgeOfScreenBottomAlignment)); | 193 kPaddingFromRightEdgeOfScreenBottomAlignment)); |
193 set_notify_enter_exit_on_child(true); | 194 set_notify_enter_exit_on_child(true); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 | 317 |
317 void SystemTray::SetDetailedViewCloseDelay(int close_delay) { | 318 void SystemTray::SetDetailedViewCloseDelay(int close_delay) { |
318 if (bubble_.get() && | 319 if (bubble_.get() && |
319 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DETAILED) | 320 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DETAILED) |
320 bubble_->StartAutoCloseTimer(close_delay); | 321 bubble_->StartAutoCloseTimer(close_delay); |
321 } | 322 } |
322 | 323 |
323 void SystemTray::HideDetailedView(SystemTrayItem* item) { | 324 void SystemTray::HideDetailedView(SystemTrayItem* item) { |
324 if (item != detailed_item_) | 325 if (item != detailed_item_) |
325 return; | 326 return; |
326 bubble_.reset(); | 327 DestroyBubble(); |
327 UpdateNotificationBubble(); | 328 UpdateNotificationBubble(); |
328 } | 329 } |
329 | 330 |
330 void SystemTray::ShowNotificationView(SystemTrayItem* item) { | 331 void SystemTray::ShowNotificationView(SystemTrayItem* item) { |
331 if (std::find(notification_items_.begin(), notification_items_.end(), item) | 332 if (std::find(notification_items_.begin(), notification_items_.end(), item) |
332 != notification_items_.end()) | 333 != notification_items_.end()) |
333 return; | 334 return; |
334 notification_items_.push_back(item); | 335 notification_items_.push_back(item); |
335 UpdateNotificationBubble(); | 336 UpdateNotificationBubble(); |
336 } | 337 } |
337 | 338 |
338 void SystemTray::HideNotificationView(SystemTrayItem* item) { | 339 void SystemTray::HideNotificationView(SystemTrayItem* item) { |
339 std::vector<SystemTrayItem*>::iterator found_iter = | 340 std::vector<SystemTrayItem*>::iterator found_iter = |
340 std::find(notification_items_.begin(), notification_items_.end(), item); | 341 std::find(notification_items_.begin(), notification_items_.end(), item); |
341 if (found_iter == notification_items_.end()) | 342 if (found_iter == notification_items_.end()) |
342 return; | 343 return; |
343 notification_items_.erase(found_iter); | 344 notification_items_.erase(found_iter); |
344 // Only update the notification bubble if visible (i.e. don't create one). | 345 // Only update the notification bubble if visible (i.e. don't create one). |
345 if (notification_bubble_.get()) | 346 if (notification_bubble_.get()) |
346 UpdateNotificationBubble(); | 347 UpdateNotificationBubble(); |
347 } | 348 } |
348 | 349 |
349 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) { | 350 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) { |
350 bubble_.reset(); | 351 DestroyBubble(); |
351 | 352 |
352 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); | 353 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); |
353 it != items_.end(); | 354 it != items_.end(); |
354 ++it) { | 355 ++it) { |
355 (*it)->UpdateAfterLoginStatusChange(login_status); | 356 (*it)->UpdateAfterLoginStatusChange(login_status); |
356 } | 357 } |
357 | 358 |
358 SetVisible(true); | 359 SetVisible(true); |
359 PreferredSizeChanged(); | 360 PreferredSizeChanged(); |
360 } | 361 } |
361 | 362 |
362 bool SystemTray::CloseBubbleForTest() const { | 363 bool SystemTray::CloseBubbleForTest() const { |
363 if (!bubble_.get()) | 364 if (!bubble_.get()) |
364 return false; | 365 return false; |
365 bubble_->Close(); | 366 bubble_->Close(); |
366 return true; | 367 return true; |
367 } | 368 } |
368 | 369 |
369 // Private methods. | 370 // Private methods. |
370 | 371 |
| 372 void SystemTray::DestroyBubble() { |
| 373 bubble_.reset(); |
| 374 detailed_item_ = NULL; |
| 375 } |
| 376 |
371 void SystemTray::RemoveBubble(SystemTrayBubble* bubble) { | 377 void SystemTray::RemoveBubble(SystemTrayBubble* bubble) { |
372 if (bubble == bubble_.get()) { | 378 if (bubble == bubble_.get()) { |
373 bubble_.reset(); | 379 DestroyBubble(); |
374 UpdateNotificationBubble(); // State changed, re-create notifications. | 380 UpdateNotificationBubble(); // State changed, re-create notifications. |
375 if (should_show_launcher_) { | 381 if (should_show_launcher_) { |
376 // No need to show the launcher if the mouse isn't over the status area | 382 // No need to show the launcher if the mouse isn't over the status area |
377 // anymore. | 383 // anymore. |
378 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow(); | 384 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow(); |
379 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains( | 385 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains( |
380 root->last_mouse_location()); | 386 root->last_mouse_location()); |
381 if (!should_show_launcher_) | 387 if (!should_show_launcher_) |
382 Shell::GetInstance()->shelf()->UpdateAutoHideState(); | 388 Shell::GetInstance()->shelf()->UpdateAutoHideState(); |
383 } | 389 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 ash::Shell::GetInstance()->tray_delegate(); | 459 ash::Shell::GetInstance()->tray_delegate(); |
454 views::View* anchor = tray_container_; | 460 views::View* anchor = tray_container_; |
455 SystemTrayBubble::InitParams init_params( | 461 SystemTrayBubble::InitParams init_params( |
456 SystemTrayBubble::ANCHOR_TYPE_TRAY, | 462 SystemTrayBubble::ANCHOR_TYPE_TRAY, |
457 shelf_alignment()); | 463 shelf_alignment()); |
458 init_params.anchor = anchor; | 464 init_params.anchor = anchor; |
459 init_params.can_activate = can_activate; | 465 init_params.can_activate = can_activate; |
460 init_params.login_status = delegate->GetUserLoginStatus(); | 466 init_params.login_status = delegate->GetUserLoginStatus(); |
461 if (arrow_offset >= 0) | 467 if (arrow_offset >= 0) |
462 init_params.arrow_offset = arrow_offset; | 468 init_params.arrow_offset = arrow_offset; |
| 469 if (detailed) |
| 470 init_params.max_height = default_bubble_height_; |
463 bubble_->InitView(init_params); | 471 bubble_->InitView(init_params); |
464 } | 472 } |
| 473 // Save height of default view for creating detailed views directly. |
| 474 if (!detailed) |
| 475 default_bubble_height_ = bubble_->bubble_view()->height(); |
465 | 476 |
466 if (detailed && items.size() > 0) | 477 if (detailed && items.size() > 0) |
467 detailed_item_ = items[0]; | 478 detailed_item_ = items[0]; |
468 else | 479 else |
469 detailed_item_ = NULL; | 480 detailed_item_ = NULL; |
470 | 481 |
471 // If we have focus the shelf should be visible and we need to continue | 482 // If we have focus the shelf should be visible and we need to continue |
472 // showing the shelf when the popup is shown. | 483 // showing the shelf when the popup is shown. |
473 if (GetWidget()->IsActive()) | 484 if (GetWidget()->IsActive()) |
474 should_show_launcher_ = true; | 485 should_show_launcher_ = true; |
475 | 486 |
476 UpdateNotificationBubble(); // State changed, re-create notifications. | 487 UpdateNotificationBubble(); // State changed, re-create notifications. |
477 } | 488 } |
478 | 489 |
479 void SystemTray::UpdateNotificationBubble() { | 490 void SystemTray::UpdateNotificationBubble() { |
480 // Only show the notification buble if we have notifications and we are not | 491 // Only show the notification buble if we have notifications and we are not |
481 // showing the default bubble. | 492 // showing the default bubble. |
482 if (notification_items_.empty() || | 493 if (notification_items_.empty() || |
483 (bubble_.get() && | 494 (bubble_.get() && |
484 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DEFAULT)) { | 495 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DEFAULT)) { |
485 notification_bubble_.reset(); | 496 notification_bubble_.reset(); |
486 return; | 497 return; |
487 } | 498 } |
488 notification_bubble_.reset( | 499 if (bubble_.get() && |
489 new SystemTrayBubble(this, notification_items_, | 500 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DETAILED) { |
490 SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION)); | 501 // Skip notifications for any currently displayed detailed item. |
| 502 std::vector<SystemTrayItem*> items; |
| 503 for (std::vector<SystemTrayItem*>::iterator iter = |
| 504 notification_items_.begin(); |
| 505 iter != notification_items_.end(); ++ iter) { |
| 506 if (*iter != detailed_item_) |
| 507 items.push_back(*iter); |
| 508 } |
| 509 notification_bubble_.reset(new SystemTrayBubble( |
| 510 this, items, SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION)); |
| 511 } else { |
| 512 // Show all notifications. |
| 513 notification_bubble_.reset(new SystemTrayBubble( |
| 514 this, notification_items_, SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION)); |
| 515 } |
491 views::View* anchor; | 516 views::View* anchor; |
492 SystemTrayBubble::AnchorType anchor_type; | 517 SystemTrayBubble::AnchorType anchor_type; |
493 if (bubble_.get()) { | 518 if (bubble_.get()) { |
494 anchor = bubble_->bubble_view(); | 519 anchor = bubble_->bubble_view(); |
495 anchor_type = SystemTrayBubble::ANCHOR_TYPE_BUBBLE; | 520 anchor_type = SystemTrayBubble::ANCHOR_TYPE_BUBBLE; |
496 } else { | 521 } else { |
497 anchor = tray_container_; | 522 anchor = tray_container_; |
498 anchor_type = SystemTrayBubble::ANCHOR_TYPE_TRAY; | 523 anchor_type = SystemTrayBubble::ANCHOR_TYPE_TRAY; |
499 } | 524 } |
500 SystemTrayBubble::InitParams init_params(anchor_type, shelf_alignment()); | 525 SystemTrayBubble::InitParams init_params(anchor_type, shelf_alignment()); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 canvas->DrawFocusRect(tray_container_->bounds()); | 605 canvas->DrawFocusRect(tray_container_->bounds()); |
581 } | 606 } |
582 | 607 |
583 void SystemTray::UpdateBackground(int alpha) { | 608 void SystemTray::UpdateBackground(int alpha) { |
584 background_->set_alpha(hide_background_animator_.alpha() + | 609 background_->set_alpha(hide_background_animator_.alpha() + |
585 hover_background_animator_.alpha()); | 610 hover_background_animator_.alpha()); |
586 SchedulePaint(); | 611 SchedulePaint(); |
587 } | 612 } |
588 | 613 |
589 } // namespace ash | 614 } // namespace ash |
OLD | NEW |