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

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: Remove unused bubble_view() 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 void DestroyItemViews();
363 views::Widget* GetTrayWidget() const;
364 void StartAutoCloseTimer(int seconds);
365 void StopAutoCloseTimer();
366 void RestartAutoCloseTimer();
367 void Close();
368
369 private:
370 // Overridden from base::MessagePumpObserver.
371 virtual base::EventStatus WillProcessEvent(
372 const base::NativeEvent& event) OVERRIDE;
373 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
374 // Overridden from views::Widget::Observer.
375 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
376 virtual void OnWidgetVisibilityChanged(views::Widget* widget,
377 bool visible) OVERRIDE;
378
379 ash::SystemTray* tray_;
380 SystemTrayBubbleView* bubble_view_;
381 views::Widget* bubble_widget_;
382 std::vector<ash::SystemTrayItem*> items_;
383 bool detailed_;
384
385 int autoclose_delay_;
386 base::OneShotTimer<SystemTrayBubble> autoclose_;
387
388 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble);
389 };
390
391 // SystemTrayBubbleView
392
393 SystemTrayBubbleView::SystemTrayBubbleView(views::View* anchor,
394 SystemTrayBubble* host,
395 bool can_activate)
396 : views::BubbleDelegateView(anchor, views::BubbleBorder::BOTTOM_RIGHT),
397 host_(host),
398 can_activate_(can_activate) {
399 set_margin(0);
400 set_parent_window(ash::Shell::GetInstance()->GetContainer(
401 ash::internal::kShellWindowId_SettingBubbleContainer));
402 set_notify_enter_exit_on_child(true);
403 }
404
405 SystemTrayBubbleView::~SystemTrayBubbleView() {
406 // Inform host items (models) that their views are being destroyed.
407 if (host_)
408 host_->DestroyItemViews();
409 }
410
411 void SystemTrayBubbleView::Init() {
412 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 1, 1, 1));
413 set_background(new SystemTrayBubbleBackground(this));
414 }
415
416 gfx::Rect SystemTrayBubbleView::GetAnchorRect() OVERRIDE {
417 if (host_) {
418 views::Widget* widget = host_->GetTrayWidget();
383 if (widget->IsVisible()) { 419 if (widget->IsVisible()) {
384 gfx::Rect rect = widget->GetWindowScreenBounds(); 420 gfx::Rect rect = widget->GetWindowScreenBounds();
385 rect.Inset( 421 rect.Inset(
386 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, 0, 422 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, 0,
387 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen, 423 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen,
388 kPaddingFromBottomOfScreen); 424 kPaddingFromBottomOfScreen);
389 return rect; 425 return rect;
390 } 426 }
391 gfx::Rect rect = gfx::Screen::GetPrimaryMonitor().bounds(); 427 }
392 return gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 428 gfx::Rect rect = gfx::Screen::GetPrimaryMonitor().bounds();
393 rect.width() - kPaddingFromRightEdgeOfScreen, 429 return gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen :
394 rect.height() - kPaddingFromBottomOfScreen, 430 rect.width() - kPaddingFromRightEdgeOfScreen,
395 0, 0); 431 rect.height() - kPaddingFromBottomOfScreen,
432 0, 0);
433 }
434
435 void SystemTrayBubbleView::ChildPreferredSizeChanged(View* child) {
436 SizeToContents();
437 }
438
439 void SystemTrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) {
440 if (can_activate_) {
441 state->role = ui::AccessibilityTypes::ROLE_WINDOW;
442 state->name = l10n_util::GetStringUTF16(
443 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
444 }
445 }
446
447 bool SystemTrayBubbleView::CanActivate() const {
448 return can_activate_;
449 }
450
451 gfx::Size SystemTrayBubbleView::GetPreferredSize() {
452 gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
453 return gfx::Size(kTrayPopupWidth, size.height());
454 }
455
456 void SystemTrayBubbleView::OnMouseEntered(const views::MouseEvent& event) {
457 if (host_)
458 host_->StopAutoCloseTimer();
459 }
460
461 void SystemTrayBubbleView::OnMouseExited(const views::MouseEvent& event) {
462 if (host_)
463 host_->RestartAutoCloseTimer();
464 }
465
466 // SystemTrayBubble
467
468 SystemTrayBubble::SystemTrayBubble(
469 ash::SystemTray* tray,
470 const std::vector<ash::SystemTrayItem*>& items,
471 bool detailed)
472 : tray_(tray),
473 bubble_view_(NULL),
474 bubble_widget_(NULL),
475 items_(items),
476 detailed_(detailed),
477 autoclose_delay_(0) {
478 MessageLoopForUI::current()->AddObserver(this);
479 }
480
481 SystemTrayBubble::~SystemTrayBubble() {
482 MessageLoopForUI::current()->RemoveObserver(this);
483 DestroyItemViews();
484 // Reset the host pointer in bubble_view_ in case its destruction is deferred.
485 if (bubble_view_)
486 bubble_view_->reset_host();
487 if (bubble_widget_) {
488 bubble_widget_->RemoveObserver(this);
489 // This triggers the destruction of bubble_view_.
490 bubble_widget_->Close();
491 }
492 }
493
494 void SystemTrayBubble::InitView(views::View* anchor,
495 bool can_activate,
496 ash::user::LoginStatus login_status) {
497 DCHECK(bubble_view_ == NULL);
498 bubble_view_ = new SystemTrayBubbleView(anchor, this, can_activate);
499
500 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
501 it != items_.end();
502 ++it) {
503 views::View* view = detailed_ ?
504 (*it)->CreateDetailedView(login_status) :
505 (*it)->CreateDefaultView(login_status);
506 if (view)
507 bubble_view_->AddChildView(new TrayPopupItemContainer(view));
396 } 508 }
397 509
398 // Overridden from views::View. 510 DCHECK(bubble_widget_ == NULL);
399 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE { 511 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
400 SizeToContents(); 512
513
514 // Must occur after call to CreateBubble()
515 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
516 bubble_widget_->non_client_view()->frame_view()->set_background(NULL);
517 bubble_view_->SetBubbleBorder(new SystemTrayBubbleBorder(bubble_view_));
518
519 bubble_widget_->AddObserver(this);
520
521 // Setup animation.
522 ash::SetWindowVisibilityAnimationType(
523 bubble_widget_->GetNativeWindow(),
524 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
525 ash::SetWindowVisibilityAnimationTransition(
526 bubble_widget_->GetNativeWindow(),
527 ash::ANIMATE_BOTH);
528 ash::SetWindowVisibilityAnimationDuration(
529 bubble_widget_->GetNativeWindow(),
530 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
531
532 bubble_view_->Show();
533 }
534
535 void SystemTrayBubble::DestroyItemViews() {
536 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
537 it != items_.end();
538 ++it) {
539 if (detailed_)
540 (*it)->DestroyDetailedView();
541 else
542 (*it)->DestroyDefaultView();
401 } 543 }
544 }
402 545
403 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE { 546 views::Widget* SystemTrayBubble::GetTrayWidget() const {
404 if (can_activate_) { 547 return tray_->GetWidget();
405 state->role = ui::AccessibilityTypes::ROLE_WINDOW; 548 }
406 state->name = l10n_util::GetStringUTF16( 549
407 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 550 void SystemTrayBubble::StartAutoCloseTimer(int seconds) {
551 autoclose_.Stop();
552 autoclose_delay_ = seconds;
553 if (autoclose_delay_) {
554 autoclose_.Start(FROM_HERE,
555 base::TimeDelta::FromSeconds(autoclose_delay_),
556 this, &SystemTrayBubble::Close);
557 }
558 }
559
560 void SystemTrayBubble::StopAutoCloseTimer() {
561 autoclose_.Stop();
562 }
563
564 void SystemTrayBubble::RestartAutoCloseTimer() {
565 if (autoclose_delay_)
566 StartAutoCloseTimer(autoclose_delay_);
567 }
568
569 void SystemTrayBubble::Close() {
570 if (bubble_widget_)
571 bubble_widget_->Close();
572 }
573
574 base::EventStatus SystemTrayBubble::WillProcessEvent(
575 const base::NativeEvent& event) {
576 // Check if the user clicked outside of the bubble and close it if they did.
577 if (ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) {
578 gfx::Point cursor_in_view = ui::EventLocationFromNative(event);
579 views::View::ConvertPointFromScreen(bubble_view_, &cursor_in_view);
580 if (!bubble_view_->HitTest(cursor_in_view)) {
581 bubble_widget_->Close();
408 } 582 }
409 } 583 }
584 return base::EVENT_CONTINUE;
585 }
410 586
411 virtual bool CanActivate() const OVERRIDE { 587 void SystemTrayBubble::DidProcessEvent(const base::NativeEvent& event) {
412 return can_activate_; 588 }
413 }
414 589
415 virtual gfx::Size GetPreferredSize() OVERRIDE { 590 void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) {
416 gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); 591 CHECK_EQ(bubble_widget_, widget);
417 return gfx::Size(kTrayPopupWidth, size.height()); 592 MessageLoopForUI::current()->RemoveObserver(this);
418 } 593 bubble_widget_ = NULL;
594 tray_->RemoveBubble(this);
595 }
419 596
420 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE { 597 void SystemTrayBubble::OnWidgetVisibilityChanged(views::Widget* widget,
421 autoclose_.Stop(); 598 bool visible) {
422 } 599 if (!visible)
423 600 MessageLoopForUI::current()->RemoveObserver(this);
424 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE { 601 else
425 if (autoclose_delay_) { 602 MessageLoopForUI::current()->AddObserver(this);
426 autoclose_.Stop(); 603 }
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 604
444 } // namespace internal 605 } // namespace internal
445 606
607 // From system_tray_delegate.h
608
446 NetworkIconInfo::NetworkIconInfo() 609 NetworkIconInfo::NetworkIconInfo()
447 : highlight(false), 610 : highlight(false),
448 tray_icon_visible(true) { 611 tray_icon_visible(true) {
449 } 612 }
450 613
451 NetworkIconInfo::~NetworkIconInfo() { 614 NetworkIconInfo::~NetworkIconInfo() {
452 } 615 }
453 616
454 BluetoothDeviceInfo::BluetoothDeviceInfo() 617 BluetoothDeviceInfo::BluetoothDeviceInfo()
455 : connected(false) { 618 : connected(false) {
456 } 619 }
457 620
458 BluetoothDeviceInfo::~BluetoothDeviceInfo() { 621 BluetoothDeviceInfo::~BluetoothDeviceInfo() {
459 } 622 }
460 623
461 IMEInfo::IMEInfo() 624 IMEInfo::IMEInfo()
462 : selected(false) { 625 : selected(false) {
463 } 626 }
464 627
465 IMEInfo::~IMEInfo() { 628 IMEInfo::~IMEInfo() {
466 } 629 }
467 630
468 IMEPropertyInfo::IMEPropertyInfo() 631 IMEPropertyInfo::IMEPropertyInfo()
469 : selected(false) { 632 : selected(false) {
470 } 633 }
471 634
472 IMEPropertyInfo::~IMEPropertyInfo() { 635 IMEPropertyInfo::~IMEPropertyInfo() {
473 } 636 }
474 637
638 // SystemTray
639
475 SystemTray::SystemTray() 640 SystemTray::SystemTray()
476 : items_(), 641 : items_(),
477 accessibility_observer_(NULL), 642 accessibility_observer_(NULL),
478 audio_observer_(NULL), 643 audio_observer_(NULL),
479 bluetooth_observer_(NULL), 644 bluetooth_observer_(NULL),
480 brightness_observer_(NULL), 645 brightness_observer_(NULL),
481 caps_lock_observer_(NULL), 646 caps_lock_observer_(NULL),
482 clock_observer_(NULL), 647 clock_observer_(NULL),
483 ime_observer_(NULL), 648 ime_observer_(NULL),
484 network_observer_(NULL), 649 network_observer_(NULL),
485 power_status_observer_(NULL), 650 power_status_observer_(NULL),
486 update_observer_(NULL), 651 update_observer_(NULL),
487 user_observer_(NULL), 652 user_observer_(NULL),
488 widget_(NULL), 653 widget_(NULL),
489 bubble_(NULL),
490 popup_(NULL),
491 background_(new internal::SystemTrayBackground), 654 background_(new internal::SystemTrayBackground),
492 should_show_launcher_(false), 655 should_show_launcher_(false),
493 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this, 656 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this,
494 0, kTrayBackgroundAlpha)), 657 0, kTrayBackgroundAlpha)),
495 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this, 658 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this,
496 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) { 659 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) {
497 container_ = new views::View; 660 container_ = new views::View;
498 container_->SetLayoutManager(new views::BoxLayout( 661 container_->SetLayoutManager(new views::BoxLayout(
499 views::BoxLayout::kHorizontal, 0, 0, 0)); 662 views::BoxLayout::kHorizontal, 0, 0, 0));
500 container_->set_background(background_); 663 container_->set_background(background_);
501 container_->set_border( 664 container_->set_border(
502 views::Border::CreateEmptyBorder(1, 1, 1, 1)); 665 views::Border::CreateEmptyBorder(1, 1, 1, 1));
503 set_border(views::Border::CreateEmptyBorder(0, 0, 666 set_border(views::Border::CreateEmptyBorder(0, 0,
504 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen)); 667 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen));
505 set_notify_enter_exit_on_child(true); 668 set_notify_enter_exit_on_child(true);
506 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 669 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
507 AddChildView(container_); 670 AddChildView(container_);
508 671
509 // Initially we want to paint the background, but without the hover effect. 672 // Initially we want to paint the background, but without the hover effect.
510 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE); 673 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE);
511 hover_background_animator_.SetPaintsBackground(false, 674 hover_background_animator_.SetPaintsBackground(false,
512 internal::BackgroundAnimator::CHANGE_IMMEDIATE); 675 internal::BackgroundAnimator::CHANGE_IMMEDIATE);
513 } 676 }
514 677
515 SystemTray::~SystemTray() { 678 SystemTray::~SystemTray() {
679 bubble_.reset();
516 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 680 for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
517 it != items_.end(); 681 it != items_.end();
518 ++it) { 682 ++it) {
519 (*it)->DestroyTrayView(); 683 (*it)->DestroyTrayView();
520 } 684 }
521 if (popup_)
522 popup_->CloseNow();
523 } 685 }
524 686
525 void SystemTray::CreateItems() { 687 void SystemTray::CreateItems() {
526 internal::TrayVolume* tray_volume = new internal::TrayVolume(); 688 internal::TrayVolume* tray_volume = new internal::TrayVolume();
527 internal::TrayBluetooth* tray_bluetooth = new internal::TrayBluetooth(); 689 internal::TrayBluetooth* tray_bluetooth = new internal::TrayBluetooth();
528 internal::TrayBrightness* tray_brightness = new internal::TrayBrightness(); 690 internal::TrayBrightness* tray_brightness = new internal::TrayBrightness();
529 internal::TrayDate* tray_date = new internal::TrayDate(); 691 internal::TrayDate* tray_date = new internal::TrayDate();
530 internal::TrayPower* tray_power = new internal::TrayPower(); 692 internal::TrayPower* tray_power = new internal::TrayPower();
531 internal::TrayNetwork* tray_network = new internal::TrayNetwork; 693 internal::TrayNetwork* tray_network = new internal::TrayNetwork;
532 internal::TrayUser* tray_user = new internal::TrayUser; 694 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); 757 container_->AddChildViewAt(tray_item, 0);
596 PreferredSizeChanged(); 758 PreferredSizeChanged();
597 } 759 }
598 } 760 }
599 761
600 void SystemTray::RemoveTrayItem(SystemTrayItem* item) { 762 void SystemTray::RemoveTrayItem(SystemTrayItem* item) {
601 NOTIMPLEMENTED(); 763 NOTIMPLEMENTED();
602 } 764 }
603 765
604 void SystemTray::ShowDefaultView() { 766 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); 767 ShowItems(items_.get(), false, true);
614 } 768 }
615 769
616 void SystemTray::ShowDetailedView(SystemTrayItem* item, 770 void SystemTray::ShowDetailedView(SystemTrayItem* item,
617 int close_delay, 771 int close_delay,
618 bool activate) { 772 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; 773 std::vector<SystemTrayItem*> items;
628 items.push_back(item); 774 items.push_back(item);
629 ShowItems(items, true, activate); 775 ShowItems(items, true, activate);
630 bubble_->StartAutoCloseTimer(close_delay); 776 bubble_->StartAutoCloseTimer(close_delay);
631 } 777 }
632 778
633 void SystemTray::SetDetailedViewCloseDelay(int close_delay) { 779 void SystemTray::SetDetailedViewCloseDelay(int close_delay) {
634 if (bubble_ && bubble_->detailed()) 780 if (bubble_.get() && bubble_->detailed())
635 bubble_->StartAutoCloseTimer(close_delay); 781 bubble_->StartAutoCloseTimer(close_delay);
636 } 782 }
637 783
638 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) { 784 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) {
639 if (popup_) 785 bubble_.reset();
640 popup_->CloseNow();
641 786
642 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 787 for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
643 it != items_.end(); 788 it != items_.end();
644 ++it) { 789 ++it) {
645 (*it)->UpdateAfterLoginStatusChange(login_status); 790 (*it)->UpdateAfterLoginStatusChange(login_status);
646 } 791 }
647 792
648 SetVisible(true); 793 SetVisible(true);
649 PreferredSizeChanged(); 794 PreferredSizeChanged();
650 } 795 }
651 796
797 void SystemTray::RemoveBubble(internal::SystemTrayBubble* bubble) {
798 CHECK_EQ(bubble_.get(), bubble);
799 bubble_.reset();
800
801 if (should_show_launcher_) {
802 // No need to show the launcher if the mouse isn't over the status area
803 // anymore.
804 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow();
805 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains(
806 root->last_mouse_location());
807 if (!should_show_launcher_)
808 Shell::GetInstance()->shelf()->UpdateAutoHideState();
809 }
810 }
811
652 void SystemTray::SetPaintsBackground( 812 void SystemTray::SetPaintsBackground(
653 bool value, 813 bool value,
654 internal::BackgroundAnimator::ChangeType change_type) { 814 internal::BackgroundAnimator::ChangeType change_type) {
655 hide_background_animator_.SetPaintsBackground(value, change_type); 815 hide_background_animator_.SetPaintsBackground(value, change_type);
656 } 816 }
657 817
658 void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items, 818 void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items,
659 bool detailed, 819 bool detailed,
660 bool activate) { 820 bool can_activate) {
661 CHECK(!popup_); 821 // Destroy any existing bubble and create a new one.
662 CHECK(!bubble_); 822 bubble_.reset(new internal::SystemTrayBubble(this, items, detailed));
663 bubble_ = new internal::SystemTrayBubble(this, container_, items, detailed); 823 ash::SystemTrayDelegate* delegate =
664 bubble_->set_can_activate(activate); 824 ash::Shell::GetInstance()->tray_delegate();
665 popup_ = views::BubbleDelegateView::CreateBubble(bubble_); 825 bubble_->InitView(container_, can_activate, delegate->GetUserLoginStatus());
666 // If we have focus the shelf should be visible and we need to continue 826 // If we have focus the shelf should be visible and we need to continue
667 // showing the shelf when the popup is shown. 827 // showing the shelf when the popup is shown.
668 if (GetWidget()->IsActive()) 828 if (GetWidget()->IsActive())
669 should_show_launcher_ = true; 829 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 } 830 }
686 831
687 bool SystemTray::PerformAction(const views::Event& event) { 832 bool SystemTray::PerformAction(const views::Event& event) {
688 // If we're already showing the default view, hide it; otherwise, show it 833 // If we're already showing the default view, hide it; otherwise, show it
689 // (and hide any popup that's currently shown). 834 // (and hide any popup that's currently shown).
690 if (popup_ && bubble_ && !bubble_->detailed()) 835 if (bubble_.get() && !bubble_->detailed())
691 popup_->Hide(); 836 bubble_->Close();
692 else 837 else
693 ShowDefaultView(); 838 ShowDefaultView();
694 return true; 839 return true;
695 } 840 }
696 841
697 void SystemTray::OnMouseEntered(const views::MouseEvent& event) { 842 void SystemTray::OnMouseEntered(const views::MouseEvent& event) {
698 should_show_launcher_ = true; 843 should_show_launcher_ = true;
699 hover_background_animator_.SetPaintsBackground(true, 844 hover_background_animator_.SetPaintsBackground(true,
700 internal::BackgroundAnimator::CHANGE_ANIMATE); 845 internal::BackgroundAnimator::CHANGE_ANIMATE);
701 } 846 }
702 847
703 void SystemTray::OnMouseExited(const views::MouseEvent& event) { 848 void SystemTray::OnMouseExited(const views::MouseEvent& event) {
704 // When the popup closes we'll update |should_show_launcher_|. 849 // When the popup closes we'll update |should_show_launcher_|.
705 if (!popup_) 850 if (!bubble_.get())
706 should_show_launcher_ = false; 851 should_show_launcher_ = false;
707 hover_background_animator_.SetPaintsBackground(false, 852 hover_background_animator_.SetPaintsBackground(false,
708 internal::BackgroundAnimator::CHANGE_ANIMATE); 853 internal::BackgroundAnimator::CHANGE_ANIMATE);
709 } 854 }
710 855
711 void SystemTray::AboutToRequestFocusFromTabTraversal(bool reverse) { 856 void SystemTray::AboutToRequestFocusFromTabTraversal(bool reverse) {
712 views::View* v = GetNextFocusableView(); 857 views::View* v = GetNextFocusableView();
713 if (v) 858 if (v)
714 v->AboutToRequestFocusFromTabTraversal(reverse); 859 v->AboutToRequestFocusFromTabTraversal(reverse);
715 } 860 }
716 861
717 void SystemTray::GetAccessibleState(ui::AccessibleViewState* state) { 862 void SystemTray::GetAccessibleState(ui::AccessibleViewState* state) {
718 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; 863 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
719 state->name = l10n_util::GetStringUTF16( 864 state->name = l10n_util::GetStringUTF16(
720 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 865 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
721 } 866 }
722 867
723 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) { 868 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) {
724 // The tray itself expands to the right and bottom edge of the screen to make 869 // 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 870 // sure clicking on the edges brings up the popup. However, the focus border
726 // should be only around the container. 871 // should be only around the container.
727 if (GetWidget() && GetWidget()->IsActive()) 872 if (GetWidget() && GetWidget()->IsActive())
728 canvas->DrawFocusRect(container_->bounds()); 873 canvas->DrawFocusRect(container_->bounds());
729 } 874 }
730 875
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) { 876 void SystemTray::UpdateBackground(int alpha) {
754 background_->set_alpha(hide_background_animator_.alpha() + 877 background_->set_alpha(hide_background_animator_.alpha() +
755 hover_background_animator_.alpha()); 878 hover_background_animator_.alpha());
756 SchedulePaint(); 879 SchedulePaint();
757 } 880 }
758 881
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 882 } // 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