Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: ash/system/tray/system_tray.cc

Issue 10235010: Prepare SystemTray to support notifications (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make bubble_ scoped, protect RemoveBubble. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/system/tray/system_tray.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 15 matching lines...) Expand all
26 #include "ash/system/tray_caps_lock.h" 26 #include "ash/system/tray_caps_lock.h"
27 #include "ash/system/tray_update.h" 27 #include "ash/system/tray_update.h"
28 #include "ash/system/user/tray_user.h" 28 #include "ash/system/user/tray_user.h"
29 #include "ash/system/user/login_status.h" 29 #include "ash/system/user/login_status.h"
30 #include "ash/wm/shadow_types.h" 30 #include "ash/wm/shadow_types.h"
31 #include "ash/wm/shelf_layout_manager.h" 31 #include "ash/wm/shelf_layout_manager.h"
32 #include "ash/wm/window_animations.h" 32 #include "ash/wm/window_animations.h"
33 #include "base/i18n/rtl.h" 33 #include "base/i18n/rtl.h"
34 #include "base/logging.h" 34 #include "base/logging.h"
35 #include "base/message_loop.h" 35 #include "base/message_loop.h"
36 #include "base/message_pump_observer.h"
36 #include "base/timer.h" 37 #include "base/timer.h"
37 #include "base/utf_string_conversions.h" 38 #include "base/utf_string_conversions.h"
38 #include "grit/ash_strings.h" 39 #include "grit/ash_strings.h"
39 #include "third_party/skia/include/core/SkCanvas.h" 40 #include "third_party/skia/include/core/SkCanvas.h"
40 #include "third_party/skia/include/core/SkColor.h" 41 #include "third_party/skia/include/core/SkColor.h"
41 #include "third_party/skia/include/core/SkPaint.h" 42 #include "third_party/skia/include/core/SkPaint.h"
42 #include "third_party/skia/include/core/SkPath.h" 43 #include "third_party/skia/include/core/SkPath.h"
43 #include "third_party/skia/include/effects/SkBlurImageFilter.h" 44 #include "third_party/skia/include/effects/SkBlurImageFilter.h"
44 #include "ui/aura/root_window.h" 45 #include "ui/aura/root_window.h"
45 #include "ui/base/events.h" 46 #include "ui/base/events.h"
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 SkScalar radius = SkIntToScalar(kTrayRoundedBorderRadius); 302 SkScalar radius = SkIntToScalar(kTrayRoundedBorderRadius);
302 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius); 303 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius);
303 canvas->DrawPath(path, paint); 304 canvas->DrawPath(path, paint);
304 } 305 }
305 306
306 int alpha_; 307 int alpha_;
307 308
308 DISALLOW_COPY_AND_ASSIGN(SystemTrayBackground); 309 DISALLOW_COPY_AND_ASSIGN(SystemTrayBackground);
309 }; 310 };
310 311
311 class SystemTrayBubble : public views::BubbleDelegateView { 312 class SystemTrayBubble;
313
314 class SystemTrayBubbleView : public views::BubbleDelegateView {
312 public: 315 public:
313 SystemTrayBubble(ash::SystemTray* tray, 316 SystemTrayBubbleView(views::View* anchor,
314 views::View* anchor, 317 SystemTrayBubble* host,
315 const std::vector<ash::SystemTrayItem*>& items, 318 bool can_activate);
316 bool detailed) 319 virtual ~SystemTrayBubbleView();
317 : views::BubbleDelegateView(anchor, views::BubbleBorder::BOTTOM_RIGHT),
318 tray_(tray),
319 items_(items),
320 detailed_(detailed),
321 can_activate_(true),
322 autoclose_delay_(0) {
323 set_margin(0);
324 set_parent_window(ash::Shell::GetInstance()->GetContainer(
325 ash::internal::kShellWindowId_SettingBubbleContainer));
326 set_notify_enter_exit_on_child(true);
327 }
328
329 virtual ~SystemTrayBubble() {
330 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
331 it != items_.end();
332 ++it) {
333 if (detailed_)
334 (*it)->DestroyDetailedView();
335 else
336 (*it)->DestroyDefaultView();
337 }
338 }
339
340 bool detailed() const { return detailed_; }
341 void set_can_activate(bool activate) { can_activate_ = activate; }
342 320
343 void SetBubbleBorder(views::BubbleBorder* border) { 321 void SetBubbleBorder(views::BubbleBorder* border) {
344 GetBubbleFrameView()->SetBubbleBorder(border); 322 GetBubbleFrameView()->SetBubbleBorder(border);
345 } 323 }
346 324
347 void StartAutoCloseTimer(int seconds) { 325 // Called when the host is destroyed.
348 autoclose_.Stop(); 326 void reset_host() { host_ = NULL; }
349 autoclose_delay_ = seconds;
350 if (autoclose_delay_) {
351 autoclose_.Start(FROM_HERE,
352 base::TimeDelta::FromSeconds(autoclose_delay_),
353 this, &SystemTrayBubble::AutoClose);
354 }
355 }
356 327
357 private: 328 private:
358 void AutoClose() { 329 // Overridden from views::BubbleDelegateView.
359 GetWidget()->Close(); 330 virtual void Init() OVERRIDE;
360 } 331 virtual gfx::Rect GetAnchorRect() OVERRIDE;
332 // Overridden from views::View.
333 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE;
334 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
335 virtual bool CanActivate() const OVERRIDE;
336 virtual gfx::Size GetPreferredSize() OVERRIDE;
337 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE;
338 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE;
361 339
362 // Overridden from views::BubbleDelegateView. 340 SystemTrayBubble* host_;
363 virtual void Init() OVERRIDE { 341 bool can_activate_;
364 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
365 1, 1, 1));
366 set_background(new SystemTrayBubbleBackground(this));
367 342
368 ash::SystemTrayDelegate* delegate = 343 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleView);
369 ash::Shell::GetInstance()->tray_delegate(); 344 };
370 ash::user::LoginStatus login_status = delegate->GetUserLoginStatus();
371 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
372 it != items_.end();
373 ++it) {
374 views::View* view = detailed_ ? (*it)->CreateDetailedView(login_status) :
375 (*it)->CreateDefaultView(login_status);
376 if (view)
377 AddChildView(new TrayPopupItemContainer(view));
378 }
379 }
380 345
381 virtual gfx::Rect GetAnchorRect() OVERRIDE { 346 class SystemTrayBubble : public base::MessagePumpObserver,
382 views::Widget* widget = tray_->GetWidget(); 347 public views::Widget::Observer {
348 public:
349 SystemTrayBubble(ash::SystemTray* tray,
350 const std::vector<ash::SystemTrayItem*>& items,
351 bool detailed);
352 virtual ~SystemTrayBubble();
353
354 // Creates |bubble_view_| and a child views for each member of |items_|.
355 // Also creates |bubble_widget_| and sets up animations.
356 void InitView(views::View* anchor,
357 bool can_activate,
358 ash::user::LoginStatus login_status);
359
360 bool detailed() const { return detailed_; }
361
362 SystemTrayBubbleView* bubble_view() const { return bubble_view_; }
sadrul 2012/04/30 21:01:41 This doesn't seem to be used.
stevenjb 2012/04/30 21:45:02 Good catch. Removed.
363
364 void DestroyItemViews();
365 views::Widget* GetTrayWidget() const;
366 void StartAutoCloseTimer(int seconds);
367 void StopAutoCloseTimer();
368 void RestartAutoCloseTimer();
369 void Close();
370
371 private:
372 // Overridden from base::MessagePumpObserver.
373 virtual base::EventStatus WillProcessEvent(
374 const base::NativeEvent& event) OVERRIDE;
375 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
376 // Overridden from views::Widget::Observer.
377 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
378 virtual void OnWidgetVisibilityChanged(views::Widget* widget,
379 bool visible) OVERRIDE;
380
381 ash::SystemTray* tray_;
382 SystemTrayBubbleView* bubble_view_;
383 views::Widget* bubble_widget_;
384 std::vector<ash::SystemTrayItem*> items_;
385 bool detailed_;
386
387 int autoclose_delay_;
388 base::OneShotTimer<SystemTrayBubble> autoclose_;
389
390 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble);
391 };
392
393 // SystemTrayBubbleView
394
395 SystemTrayBubbleView::SystemTrayBubbleView(views::View* anchor,
396 SystemTrayBubble* host,
397 bool can_activate)
398 : views::BubbleDelegateView(anchor, views::BubbleBorder::BOTTOM_RIGHT),
399 host_(host),
400 can_activate_(can_activate) {
401 set_margin(0);
402 set_parent_window(ash::Shell::GetInstance()->GetContainer(
403 ash::internal::kShellWindowId_SettingBubbleContainer));
404 set_notify_enter_exit_on_child(true);
405 }
406
407 SystemTrayBubbleView::~SystemTrayBubbleView() {
408 // Inform host items (models) that their views are being destroyed.
409 if (host_)
410 host_->DestroyItemViews();
411 }
412
413 void SystemTrayBubbleView::Init() {
414 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 1, 1, 1));
415 set_background(new SystemTrayBubbleBackground(this));
416 }
417
418 gfx::Rect SystemTrayBubbleView::GetAnchorRect() OVERRIDE {
419 if (host_) {
420 views::Widget* widget = host_->GetTrayWidget();
383 if (widget->IsVisible()) { 421 if (widget->IsVisible()) {
384 gfx::Rect rect = widget->GetWindowScreenBounds(); 422 gfx::Rect rect = widget->GetWindowScreenBounds();
385 rect.Inset( 423 rect.Inset(
386 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, 0, 424 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, 0,
387 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen, 425 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen,
388 kPaddingFromBottomOfScreen); 426 kPaddingFromBottomOfScreen);
389 return rect; 427 return rect;
390 } 428 }
391 gfx::Rect rect = gfx::Screen::GetPrimaryMonitor().bounds(); 429 }
392 return gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 430 gfx::Rect rect = gfx::Screen::GetPrimaryMonitor().bounds();
393 rect.width() - kPaddingFromRightEdgeOfScreen, 431 return gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen :
394 rect.height() - kPaddingFromBottomOfScreen, 432 rect.width() - kPaddingFromRightEdgeOfScreen,
395 0, 0); 433 rect.height() - kPaddingFromBottomOfScreen,
434 0, 0);
435 }
436
437 void SystemTrayBubbleView::ChildPreferredSizeChanged(View* child) {
438 SizeToContents();
439 }
440
441 void SystemTrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) {
442 if (can_activate_) {
443 state->role = ui::AccessibilityTypes::ROLE_WINDOW;
444 state->name = l10n_util::GetStringUTF16(
445 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
446 }
447 }
448
449 bool SystemTrayBubbleView::CanActivate() const {
450 return can_activate_;
451 }
452
453 gfx::Size SystemTrayBubbleView::GetPreferredSize() {
454 gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
455 return gfx::Size(kTrayPopupWidth, size.height());
456 }
457
458 void SystemTrayBubbleView::OnMouseEntered(const views::MouseEvent& event) {
459 if (host_)
460 host_->StopAutoCloseTimer();
461 }
462
463 void SystemTrayBubbleView::OnMouseExited(const views::MouseEvent& event) {
464 if (host_)
465 host_->RestartAutoCloseTimer();
466 }
467
468 // SystemTrayBubble
469
470 SystemTrayBubble::SystemTrayBubble(
471 ash::SystemTray* tray,
472 const std::vector<ash::SystemTrayItem*>& items,
473 bool detailed)
474 : tray_(tray),
475 bubble_view_(NULL),
476 bubble_widget_(NULL),
477 items_(items),
478 detailed_(detailed),
479 autoclose_delay_(0) {
480 MessageLoopForUI::current()->AddObserver(this);
481 }
482
483 SystemTrayBubble::~SystemTrayBubble() {
484 MessageLoopForUI::current()->RemoveObserver(this);
485 DestroyItemViews();
486 // Reset the host pointer in bubble_view_ in case its destruction is deferred.
487 if (bubble_view_)
488 bubble_view_->reset_host();
489 if (bubble_widget_) {
490 bubble_widget_->RemoveObserver(this);
491 // This triggers the destruction of bubble_view_.
492 bubble_widget_->Close();
493 }
494 }
495
496 void SystemTrayBubble::InitView(views::View* anchor,
497 bool can_activate,
498 ash::user::LoginStatus login_status) {
499 DCHECK(bubble_view_ == NULL);
500 bubble_view_ = new SystemTrayBubbleView(anchor, this, can_activate);
501
502 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
503 it != items_.end();
504 ++it) {
505 views::View* view = detailed_ ?
506 (*it)->CreateDetailedView(login_status) :
507 (*it)->CreateDefaultView(login_status);
508 if (view)
509 bubble_view_->AddChildView(new TrayPopupItemContainer(view));
396 } 510 }
397 511
398 // Overridden from views::View. 512 DCHECK(bubble_widget_ == NULL);
399 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE { 513 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
400 SizeToContents(); 514
515
516 // Must occur after call to CreateBubble()
517 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
518 bubble_widget_->non_client_view()->frame_view()->set_background(NULL);
519 bubble_view_->SetBubbleBorder(new SystemTrayBubbleBorder(bubble_view_));
520
521 bubble_widget_->AddObserver(this);
522
523 // Setup animation.
524 ash::SetWindowVisibilityAnimationType(
525 bubble_widget_->GetNativeWindow(),
526 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
527 ash::SetWindowVisibilityAnimationTransition(
528 bubble_widget_->GetNativeWindow(),
529 ash::ANIMATE_BOTH);
530 ash::SetWindowVisibilityAnimationDuration(
531 bubble_widget_->GetNativeWindow(),
532 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
533
534 bubble_view_->Show();
535 }
536
537 void SystemTrayBubble::DestroyItemViews() {
538 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
539 it != items_.end();
540 ++it) {
541 if (detailed_)
542 (*it)->DestroyDetailedView();
543 else
544 (*it)->DestroyDefaultView();
401 } 545 }
546 }
402 547
403 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE { 548 views::Widget* SystemTrayBubble::GetTrayWidget() const {
404 if (can_activate_) { 549 return tray_->GetWidget();
405 state->role = ui::AccessibilityTypes::ROLE_WINDOW; 550 }
406 state->name = l10n_util::GetStringUTF16( 551
407 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 552 void SystemTrayBubble::StartAutoCloseTimer(int seconds) {
553 autoclose_.Stop();
554 autoclose_delay_ = seconds;
555 if (autoclose_delay_) {
556 autoclose_.Start(FROM_HERE,
557 base::TimeDelta::FromSeconds(autoclose_delay_),
558 this, &SystemTrayBubble::Close);
559 }
560 }
561
562 void SystemTrayBubble::StopAutoCloseTimer() {
563 autoclose_.Stop();
564 }
565
566 void SystemTrayBubble::RestartAutoCloseTimer() {
567 if (autoclose_delay_)
568 StartAutoCloseTimer(autoclose_delay_);
569 }
570
571 void SystemTrayBubble::Close() {
572 if (bubble_widget_)
573 bubble_widget_->Close();
574 }
575
576 base::EventStatus SystemTrayBubble::WillProcessEvent(
577 const base::NativeEvent& event) {
578 // Check if the user clicked outside of the bubble and close it if they did.
579 if (ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) {
580 gfx::Point cursor_in_view = ui::EventLocationFromNative(event);
581 views::View::ConvertPointFromScreen(bubble_view_, &cursor_in_view);
582 if (!bubble_view_->HitTest(cursor_in_view)) {
583 bubble_widget_->Close();
408 } 584 }
409 } 585 }
586 return base::EVENT_CONTINUE;
587 }
410 588
411 virtual bool CanActivate() const OVERRIDE { 589 void SystemTrayBubble::DidProcessEvent(const base::NativeEvent& event) {
412 return can_activate_; 590 }
413 }
414 591
415 virtual gfx::Size GetPreferredSize() OVERRIDE { 592 void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) {
416 gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); 593 CHECK_EQ(bubble_widget_, widget);
417 return gfx::Size(kTrayPopupWidth, size.height()); 594 MessageLoopForUI::current()->RemoveObserver(this);
418 } 595 bubble_widget_ = NULL;
596 tray_->RemoveBubble(this);
597 }
419 598
420 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE { 599 void SystemTrayBubble::OnWidgetVisibilityChanged(views::Widget* widget,
421 autoclose_.Stop(); 600 bool visible) {
422 } 601 if (!visible)
423 602 MessageLoopForUI::current()->RemoveObserver(this);
424 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE { 603 else
425 if (autoclose_delay_) { 604 MessageLoopForUI::current()->AddObserver(this);
426 autoclose_.Stop(); 605 }
427 autoclose_.Start(FROM_HERE,
428 base::TimeDelta::FromSeconds(autoclose_delay_),
429 this, &SystemTrayBubble::AutoClose);
430 }
431 }
432
433 ash::SystemTray* tray_;
434 std::vector<ash::SystemTrayItem*> items_;
435 bool detailed_;
436 bool can_activate_;
437
438 int autoclose_delay_;
439 base::OneShotTimer<SystemTrayBubble> autoclose_;
440
441 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble);
442 };
443 606
444 } // namespace internal 607 } // namespace internal
445 608
609 // From system_tray_delegate.h
610
446 NetworkIconInfo::NetworkIconInfo() 611 NetworkIconInfo::NetworkIconInfo()
447 : highlight(false), 612 : highlight(false),
448 tray_icon_visible(true) { 613 tray_icon_visible(true) {
449 } 614 }
450 615
451 NetworkIconInfo::~NetworkIconInfo() { 616 NetworkIconInfo::~NetworkIconInfo() {
452 } 617 }
453 618
454 BluetoothDeviceInfo::BluetoothDeviceInfo() 619 BluetoothDeviceInfo::BluetoothDeviceInfo()
455 : connected(false) { 620 : connected(false) {
456 } 621 }
457 622
458 BluetoothDeviceInfo::~BluetoothDeviceInfo() { 623 BluetoothDeviceInfo::~BluetoothDeviceInfo() {
459 } 624 }
460 625
461 IMEInfo::IMEInfo() 626 IMEInfo::IMEInfo()
462 : selected(false) { 627 : selected(false) {
463 } 628 }
464 629
465 IMEInfo::~IMEInfo() { 630 IMEInfo::~IMEInfo() {
466 } 631 }
467 632
468 IMEPropertyInfo::IMEPropertyInfo() 633 IMEPropertyInfo::IMEPropertyInfo()
469 : selected(false) { 634 : selected(false) {
470 } 635 }
471 636
472 IMEPropertyInfo::~IMEPropertyInfo() { 637 IMEPropertyInfo::~IMEPropertyInfo() {
473 } 638 }
474 639
640 // SystemTray
641
475 SystemTray::SystemTray() 642 SystemTray::SystemTray()
476 : items_(), 643 : items_(),
477 accessibility_observer_(NULL), 644 accessibility_observer_(NULL),
478 audio_observer_(NULL), 645 audio_observer_(NULL),
479 bluetooth_observer_(NULL), 646 bluetooth_observer_(NULL),
480 brightness_observer_(NULL), 647 brightness_observer_(NULL),
481 caps_lock_observer_(NULL), 648 caps_lock_observer_(NULL),
482 clock_observer_(NULL), 649 clock_observer_(NULL),
483 ime_observer_(NULL), 650 ime_observer_(NULL),
484 network_observer_(NULL), 651 network_observer_(NULL),
485 power_status_observer_(NULL), 652 power_status_observer_(NULL),
486 update_observer_(NULL), 653 update_observer_(NULL),
487 user_observer_(NULL), 654 user_observer_(NULL),
488 widget_(NULL), 655 widget_(NULL),
489 bubble_(NULL),
490 popup_(NULL),
491 background_(new internal::SystemTrayBackground), 656 background_(new internal::SystemTrayBackground),
492 should_show_launcher_(false), 657 should_show_launcher_(false),
493 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this, 658 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this,
494 0, kTrayBackgroundAlpha)), 659 0, kTrayBackgroundAlpha)),
495 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this, 660 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this,
496 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) { 661 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) {
497 container_ = new views::View; 662 container_ = new views::View;
498 container_->SetLayoutManager(new views::BoxLayout( 663 container_->SetLayoutManager(new views::BoxLayout(
499 views::BoxLayout::kHorizontal, 0, 0, 0)); 664 views::BoxLayout::kHorizontal, 0, 0, 0));
500 container_->set_background(background_); 665 container_->set_background(background_);
501 container_->set_border( 666 container_->set_border(
502 views::Border::CreateEmptyBorder(1, 1, 1, 1)); 667 views::Border::CreateEmptyBorder(1, 1, 1, 1));
503 set_border(views::Border::CreateEmptyBorder(0, 0, 668 set_border(views::Border::CreateEmptyBorder(0, 0,
504 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen)); 669 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen));
505 set_notify_enter_exit_on_child(true); 670 set_notify_enter_exit_on_child(true);
506 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 671 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
507 AddChildView(container_); 672 AddChildView(container_);
508 673
509 // Initially we want to paint the background, but without the hover effect. 674 // Initially we want to paint the background, but without the hover effect.
510 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE); 675 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE);
511 hover_background_animator_.SetPaintsBackground(false, 676 hover_background_animator_.SetPaintsBackground(false,
512 internal::BackgroundAnimator::CHANGE_IMMEDIATE); 677 internal::BackgroundAnimator::CHANGE_IMMEDIATE);
513 } 678 }
514 679
515 SystemTray::~SystemTray() { 680 SystemTray::~SystemTray() {
681 bubble_.reset();
516 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 682 for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
517 it != items_.end(); 683 it != items_.end();
518 ++it) { 684 ++it) {
519 (*it)->DestroyTrayView(); 685 (*it)->DestroyTrayView();
520 } 686 }
521 if (popup_)
522 popup_->CloseNow();
523 } 687 }
524 688
525 void SystemTray::CreateItems() { 689 void SystemTray::CreateItems() {
526 internal::TrayVolume* tray_volume = new internal::TrayVolume(); 690 internal::TrayVolume* tray_volume = new internal::TrayVolume();
527 internal::TrayBluetooth* tray_bluetooth = new internal::TrayBluetooth(); 691 internal::TrayBluetooth* tray_bluetooth = new internal::TrayBluetooth();
528 internal::TrayBrightness* tray_brightness = new internal::TrayBrightness(); 692 internal::TrayBrightness* tray_brightness = new internal::TrayBrightness();
529 internal::TrayDate* tray_date = new internal::TrayDate(); 693 internal::TrayDate* tray_date = new internal::TrayDate();
530 internal::TrayPower* tray_power = new internal::TrayPower(); 694 internal::TrayPower* tray_power = new internal::TrayPower();
531 internal::TrayNetwork* tray_network = new internal::TrayNetwork; 695 internal::TrayNetwork* tray_network = new internal::TrayNetwork;
532 internal::TrayUser* tray_user = new internal::TrayUser; 696 internal::TrayUser* tray_user = new internal::TrayUser;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 container_->AddChildViewAt(tray_item, 0); 759 container_->AddChildViewAt(tray_item, 0);
596 PreferredSizeChanged(); 760 PreferredSizeChanged();
597 } 761 }
598 } 762 }
599 763
600 void SystemTray::RemoveTrayItem(SystemTrayItem* item) { 764 void SystemTray::RemoveTrayItem(SystemTrayItem* item) {
601 NOTIMPLEMENTED(); 765 NOTIMPLEMENTED();
602 } 766 }
603 767
604 void SystemTray::ShowDefaultView() { 768 void SystemTray::ShowDefaultView() {
605 if (popup_) {
606 MessageLoopForUI::current()->RemoveObserver(this);
607 popup_->RemoveObserver(this);
608 popup_->Close();
609 }
610 popup_ = NULL;
611 bubble_ = NULL;
612
613 ShowItems(items_.get(), false, true); 769 ShowItems(items_.get(), false, true);
614 } 770 }
615 771
616 void SystemTray::ShowDetailedView(SystemTrayItem* item, 772 void SystemTray::ShowDetailedView(SystemTrayItem* item,
617 int close_delay, 773 int close_delay,
618 bool activate) { 774 bool activate) {
619 if (popup_) {
620 MessageLoopForUI::current()->RemoveObserver(this);
621 popup_->RemoveObserver(this);
622 popup_->Close();
623 }
624 popup_ = NULL;
625 bubble_ = NULL;
626
627 std::vector<SystemTrayItem*> items; 775 std::vector<SystemTrayItem*> items;
628 items.push_back(item); 776 items.push_back(item);
629 ShowItems(items, true, activate); 777 ShowItems(items, true, activate);
630 bubble_->StartAutoCloseTimer(close_delay); 778 bubble_->StartAutoCloseTimer(close_delay);
631 } 779 }
632 780
633 void SystemTray::SetDetailedViewCloseDelay(int close_delay) { 781 void SystemTray::SetDetailedViewCloseDelay(int close_delay) {
634 if (bubble_ && bubble_->detailed()) 782 if (bubble_.get() && bubble_->detailed())
635 bubble_->StartAutoCloseTimer(close_delay); 783 bubble_->StartAutoCloseTimer(close_delay);
636 } 784 }
637 785
638 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) { 786 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) {
639 if (popup_) 787 bubble_.reset();
640 popup_->CloseNow();
641 788
642 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 789 for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
643 it != items_.end(); 790 it != items_.end();
644 ++it) { 791 ++it) {
645 (*it)->UpdateAfterLoginStatusChange(login_status); 792 (*it)->UpdateAfterLoginStatusChange(login_status);
646 } 793 }
647 794
648 SetVisible(true); 795 SetVisible(true);
649 PreferredSizeChanged(); 796 PreferredSizeChanged();
650 } 797 }
651 798
799 void SystemTray::RemoveBubble(internal::SystemTrayBubble* bubble) {
800 CHECK_EQ(bubble_.get(), bubble);
801 bubble_.reset();
802
803 if (should_show_launcher_) {
804 // No need to show the launcher if the mouse isn't over the status area
805 // anymore.
806 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow();
807 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains(
808 root->last_mouse_location());
809 if (!should_show_launcher_)
810 Shell::GetInstance()->shelf()->UpdateAutoHideState();
811 }
812 }
813
652 void SystemTray::SetPaintsBackground( 814 void SystemTray::SetPaintsBackground(
653 bool value, 815 bool value,
654 internal::BackgroundAnimator::ChangeType change_type) { 816 internal::BackgroundAnimator::ChangeType change_type) {
655 hide_background_animator_.SetPaintsBackground(value, change_type); 817 hide_background_animator_.SetPaintsBackground(value, change_type);
656 } 818 }
657 819
658 void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items, 820 void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items,
659 bool detailed, 821 bool detailed,
660 bool activate) { 822 bool can_activate) {
661 CHECK(!popup_); 823 // Destroy any existing bubble and create a new one.
662 CHECK(!bubble_); 824 bubble_.reset(new internal::SystemTrayBubble(this, items, detailed));
663 bubble_ = new internal::SystemTrayBubble(this, container_, items, detailed); 825 ash::SystemTrayDelegate* delegate =
664 bubble_->set_can_activate(activate); 826 ash::Shell::GetInstance()->tray_delegate();
665 popup_ = views::BubbleDelegateView::CreateBubble(bubble_); 827 bubble_->InitView(container_, can_activate, delegate->GetUserLoginStatus());
666 // If we have focus the shelf should be visible and we need to continue 828 // If we have focus the shelf should be visible and we need to continue
667 // showing the shelf when the popup is shown. 829 // showing the shelf when the popup is shown.
668 if (GetWidget()->IsActive()) 830 if (GetWidget()->IsActive())
669 should_show_launcher_ = true; 831 should_show_launcher_ = true;
670 bubble_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
671 popup_->non_client_view()->frame_view()->set_background(NULL);
672 bubble_->SetBubbleBorder(new SystemTrayBubbleBorder(bubble_));
673 MessageLoopForUI::current()->AddObserver(this);
674 popup_->AddObserver(this);
675
676 // Setup animation.
677 ash::SetWindowVisibilityAnimationType(popup_->GetNativeWindow(),
678 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
679 ash::SetWindowVisibilityAnimationTransition(popup_->GetNativeWindow(),
680 ash::ANIMATE_BOTH);
681 ash::SetWindowVisibilityAnimationDuration(popup_->GetNativeWindow(),
682 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
683
684 bubble_->Show();
685 } 832 }
686 833
687 bool SystemTray::PerformAction(const views::Event& event) { 834 bool SystemTray::PerformAction(const views::Event& event) {
688 // If we're already showing the default view, hide it; otherwise, show it 835 // If we're already showing the default view, hide it; otherwise, show it
689 // (and hide any popup that's currently shown). 836 // (and hide any popup that's currently shown).
690 if (popup_ && bubble_ && !bubble_->detailed()) 837 if (bubble_.get() && !bubble_->detailed())
691 popup_->Hide(); 838 bubble_->Close();
692 else 839 else
693 ShowDefaultView(); 840 ShowDefaultView();
694 return true; 841 return true;
695 } 842 }
696 843
697 void SystemTray::OnMouseEntered(const views::MouseEvent& event) { 844 void SystemTray::OnMouseEntered(const views::MouseEvent& event) {
698 should_show_launcher_ = true; 845 should_show_launcher_ = true;
699 hover_background_animator_.SetPaintsBackground(true, 846 hover_background_animator_.SetPaintsBackground(true,
700 internal::BackgroundAnimator::CHANGE_ANIMATE); 847 internal::BackgroundAnimator::CHANGE_ANIMATE);
701 } 848 }
702 849
703 void SystemTray::OnMouseExited(const views::MouseEvent& event) { 850 void SystemTray::OnMouseExited(const views::MouseEvent& event) {
704 // When the popup closes we'll update |should_show_launcher_|. 851 // When the popup closes we'll update |should_show_launcher_|.
705 if (!popup_) 852 if (!bubble_.get())
706 should_show_launcher_ = false; 853 should_show_launcher_ = false;
707 hover_background_animator_.SetPaintsBackground(false, 854 hover_background_animator_.SetPaintsBackground(false,
708 internal::BackgroundAnimator::CHANGE_ANIMATE); 855 internal::BackgroundAnimator::CHANGE_ANIMATE);
709 } 856 }
710 857
711 void SystemTray::AboutToRequestFocusFromTabTraversal(bool reverse) { 858 void SystemTray::AboutToRequestFocusFromTabTraversal(bool reverse) {
712 views::View* v = GetNextFocusableView(); 859 views::View* v = GetNextFocusableView();
713 if (v) 860 if (v)
714 v->AboutToRequestFocusFromTabTraversal(reverse); 861 v->AboutToRequestFocusFromTabTraversal(reverse);
715 } 862 }
716 863
717 void SystemTray::GetAccessibleState(ui::AccessibleViewState* state) { 864 void SystemTray::GetAccessibleState(ui::AccessibleViewState* state) {
718 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; 865 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
719 state->name = l10n_util::GetStringUTF16( 866 state->name = l10n_util::GetStringUTF16(
720 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 867 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
721 } 868 }
722 869
723 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) { 870 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) {
724 // The tray itself expands to the right and bottom edge of the screen to make 871 // The tray itself expands to the right and bottom edge of the screen to make
725 // sure clicking on the edges brings up the popup. However, the focus border 872 // sure clicking on the edges brings up the popup. However, the focus border
726 // should be only around the container. 873 // should be only around the container.
727 if (GetWidget() && GetWidget()->IsActive()) 874 if (GetWidget() && GetWidget()->IsActive())
728 canvas->DrawFocusRect(container_->bounds()); 875 canvas->DrawFocusRect(container_->bounds());
729 } 876 }
730 877
731 void SystemTray::OnWidgetClosing(views::Widget* widget) {
732 CHECK_EQ(popup_, widget);
733 MessageLoopForUI::current()->RemoveObserver(this);
734 popup_ = NULL;
735 bubble_ = NULL;
736 if (should_show_launcher_) {
737 // No need to show the launcher if the mouse isn't over the status area
738 // anymore.
739 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow();
740 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains(
741 root->last_mouse_location());
742 if (!should_show_launcher_)
743 Shell::GetInstance()->shelf()->UpdateAutoHideState();
744 }
745 }
746
747 void SystemTray::OnWidgetVisibilityChanged(views::Widget* widget,
748 bool visible) {
749 if (!visible)
750 MessageLoopForUI::current()->RemoveObserver(this);
751 }
752
753 void SystemTray::UpdateBackground(int alpha) { 878 void SystemTray::UpdateBackground(int alpha) {
754 background_->set_alpha(hide_background_animator_.alpha() + 879 background_->set_alpha(hide_background_animator_.alpha() +
755 hover_background_animator_.alpha()); 880 hover_background_animator_.alpha());
756 SchedulePaint(); 881 SchedulePaint();
757 } 882 }
758 883
759 base::EventStatus SystemTray::WillProcessEvent(const base::NativeEvent& event) {
760 // Check if the user clicked outside of the system tray bubble and hide it
761 // if they did.
762 if (bubble_ && ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) {
763 gfx::Point cursor_in_view = ui::EventLocationFromNative(event);
764 View::ConvertPointFromScreen(bubble_, &cursor_in_view);
765 if (!bubble_->HitTest(cursor_in_view)) {
766 popup_->Hide();
767 }
768 }
769 return base::EVENT_CONTINUE;
770 }
771
772 void SystemTray::DidProcessEvent(const base::NativeEvent& event) {
773 }
774
775 } // namespace ash 884 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/tray/system_tray.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698