OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/system/web_notification/web_notification_tray.h" | 5 #include "ash/system/web_notification/web_notification_tray.h" |
6 | 6 |
7 #include "ash/system/status_area_widget.h" | 7 #include "ash/system/status_area_widget.h" |
8 #include "ash/system/tray/tray_bubble_view.h" | 8 #include "ash/system/tray/tray_bubble_view.h" |
9 #include "ash/system/tray/tray_constants.h" | 9 #include "ash/system/tray/tray_constants.h" |
10 #include "ash/system/tray/tray_views.h" | 10 #include "ash/system/tray/tray_views.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 const int kTrayContainerVerticalPaddingVerticalAlignment = 1; | 35 const int kTrayContainerVerticalPaddingVerticalAlignment = 1; |
36 const int kTrayContainerHorizontalPaddingVerticalAlignment = 0; | 36 const int kTrayContainerHorizontalPaddingVerticalAlignment = 0; |
37 const int kPaddingFromLeftEdgeOfSystemTrayBottomAlignment = 8; | 37 const int kPaddingFromLeftEdgeOfSystemTrayBottomAlignment = 8; |
38 const int kPaddingFromTopEdgeOfSystemTrayVerticalAlignment = 10; | 38 const int kPaddingFromTopEdgeOfSystemTrayVerticalAlignment = 10; |
39 const int kNotificationImageIconWidth = 40; | 39 const int kNotificationImageIconWidth = 40; |
40 const int kNotificationImageIconHeight = 25; | 40 const int kNotificationImageIconHeight = 25; |
41 const int kNotificationImageIconInset = 4; | 41 const int kNotificationImageIconInset = 4; |
42 | 42 |
43 // Web Notification Bubble constants | 43 // Web Notification Bubble constants |
44 const int kWebNotificationBubbleMinHeight = 80; | 44 const int kWebNotificationBubbleMinHeight = 80; |
45 const int kWebNotificationBubbleMaxHeight = 400; | 45 const int kWebNotificationBubbleMaxHeight = 480; |
46 // Delay laying out the Bubble until all notifications have been added and icons | 46 // Delay laying out the Bubble until all notifications have been added and icons |
47 // have had a chance to load. | 47 // have had a chance to load. |
48 const int kUpdateDelayMs = 50; | 48 const int kUpdateDelayMs = 50; |
49 // Limit the number of visible notifications. | 49 // Limit the number of visible notifications. |
50 const int kMaxVisibleNotifications = 100; | 50 const int kMaxVisibleNotifications = 100; |
51 | 51 |
52 // Individual notifications constants | 52 // Individual notifications constants |
53 const int kWebNotificationWidth = 400; | 53 const int kWebNotificationWidth = 320; |
54 const int kWebNotificationButtonWidth = 32; | 54 const int kWebNotificationButtonWidth = 32; |
55 const int kWebNotificationIconSize = 40; | 55 const int kWebNotificationIconSize = 40; |
56 | 56 |
57 // Menu constants | 57 // Menu constants |
58 const int kTogglePermissionCommand = 0; | 58 const int kTogglePermissionCommand = 0; |
59 const int kToggleExtensionCommand = 1; | 59 const int kToggleExtensionCommand = 1; |
60 const int kShowSettingsCommand = 2; | 60 const int kShowSettingsCommand = 2; |
61 | 61 |
62 // The image has three icons: 1 notifiaction, 2 notifications, and 3+. | 62 // The image has three icons: 1 notifiaction, 2 notifications, and 3+. |
63 SkBitmap GetNotificationImage(int notification_count) { | 63 SkBitmap GetNotificationImage(int notification_count) { |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 private: | 476 private: |
477 WebNotificationTray* tray_; | 477 WebNotificationTray* tray_; |
478 TrayPopupTextButton* settings_button_; | 478 TrayPopupTextButton* settings_button_; |
479 TrayPopupTextButton* close_all_button_; | 479 TrayPopupTextButton* close_all_button_; |
480 | 480 |
481 DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonView); | 481 DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonView); |
482 }; | 482 }; |
483 | 483 |
484 } // namespace internal | 484 } // namespace internal |
485 | 485 |
| 486 using internal::TrayBubbleView; |
486 using internal::WebNotificationList; | 487 using internal::WebNotificationList; |
487 using internal::WebNotificationView; | 488 using internal::WebNotificationView; |
488 | 489 |
489 class WebNotificationTray::BubbleContentsView : public views::View { | 490 class WebNotificationTray::BubbleContentsView : public views::View { |
490 public: | 491 public: |
491 explicit BubbleContentsView(WebNotificationTray* tray) | 492 explicit BubbleContentsView(WebNotificationTray* tray) |
492 : tray_(tray) { | 493 : tray_(tray) { |
493 set_border(views::Border::CreateSolidSidedBorder( | 494 set_border(views::Border::CreateSolidSidedBorder( |
494 1, 1, 1, 1, ash::kBorderDarkColor)); | 495 1, 1, 1, 1, ash::kBorderDarkColor)); |
495 | 496 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 } | 561 } |
561 | 562 |
562 WebNotificationTray* tray_; | 563 WebNotificationTray* tray_; |
563 internal::FixedSizedScrollView* scroller_; | 564 internal::FixedSizedScrollView* scroller_; |
564 views::View* scroll_content_; | 565 views::View* scroll_content_; |
565 internal::WebNotificationButtonView* button_view_; | 566 internal::WebNotificationButtonView* button_view_; |
566 | 567 |
567 DISALLOW_COPY_AND_ASSIGN(BubbleContentsView); | 568 DISALLOW_COPY_AND_ASSIGN(BubbleContentsView); |
568 }; | 569 }; |
569 | 570 |
570 class WebNotificationTray::Bubble : public internal::TrayBubbleView::Host, | 571 class WebNotificationTray::Bubble : public TrayBubbleView::Host, |
571 public views::Widget::Observer { | 572 public views::Widget::Observer { |
572 public: | 573 public: |
573 explicit Bubble(WebNotificationTray* tray) | 574 explicit Bubble(WebNotificationTray* tray) |
574 : tray_(tray), | 575 : tray_(tray), |
575 bubble_view_(NULL), | 576 bubble_view_(NULL), |
576 bubble_widget_(NULL), | 577 bubble_widget_(NULL), |
577 contents_view_(NULL), | 578 contents_view_(NULL), |
578 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 579 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
579 views::View* anchor = tray->tray_container(); | 580 views::View* anchor = tray->tray_container(); |
580 views::BubbleBorder::ArrowLocation arrow_location; | 581 TrayBubbleView::InitParams init_params(TrayBubbleView::ANCHOR_TYPE_TRAY, |
581 int arrow_offset = 0; | 582 tray->shelf_alignment()); |
| 583 init_params.bubble_width = kWebNotificationWidth; |
| 584 init_params.max_height = kWebNotificationBubbleMaxHeight; |
582 if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) { | 585 if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) { |
583 arrow_location = views::BubbleBorder::BOTTOM_RIGHT; | 586 gfx::Rect bounds(anchor->width() / 2, 0, 0, 0); |
584 arrow_offset = anchor->GetContentsBounds().width() / 2; | 587 bounds = anchor->ConvertRectToWidget(bounds); |
585 } else if (tray_->shelf_alignment() == SHELF_ALIGNMENT_LEFT) { | 588 init_params.arrow_offset = bounds.x(); |
586 arrow_location = views::BubbleBorder::LEFT_BOTTOM; | |
587 } else { | |
588 arrow_location = views::BubbleBorder::RIGHT_BOTTOM; | |
589 } | 589 } |
590 bubble_view_ = new internal::TrayBubbleView( | 590 bubble_view_ = TrayBubbleView::Create(anchor, this, init_params); |
591 anchor, arrow_location, this, false, kWebNotificationWidth); | |
592 bubble_view_->SetMaxHeight(kWebNotificationBubbleMaxHeight); | |
593 | |
594 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_); | |
595 | |
596 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); | |
597 bubble_widget_->non_client_view()->frame_view()->set_background(NULL); | |
598 bubble_view_->SetBubbleBorder(arrow_offset); | |
599 | |
600 bubble_widget_->AddObserver(this); | |
601 | 591 |
602 contents_view_ = new BubbleContentsView(tray); | 592 contents_view_ = new BubbleContentsView(tray); |
603 bubble_view_->AddChildView(contents_view_); | 593 bubble_view_->AddChildView(contents_view_); |
604 | 594 |
605 InitializeHost(bubble_widget_, tray_); | 595 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_); |
| 596 bubble_widget_->AddObserver(this); |
| 597 |
| 598 PostCreateBubble(bubble_widget_, bubble_view_, tray_); |
606 | 599 |
607 ScheduleUpdate(); | 600 ScheduleUpdate(); |
608 } | 601 } |
609 | 602 |
610 virtual ~Bubble() { | 603 virtual ~Bubble() { |
611 if (bubble_view_) | 604 if (bubble_view_) |
612 bubble_view_->reset_host(); | 605 bubble_view_->reset_host(); |
613 if (bubble_widget_) { | 606 if (bubble_widget_) { |
614 bubble_widget_->RemoveObserver(this); | 607 bubble_widget_->RemoveObserver(this); |
615 bubble_widget_->Close(); | 608 bubble_widget_->Close(); |
(...skipping 10 matching lines...) Expand all Loading... |
626 } | 619 } |
627 | 620 |
628 views::Widget* bubble_widget() const { return bubble_widget_; } | 621 views::Widget* bubble_widget() const { return bubble_widget_; } |
629 | 622 |
630 // Overridden from TrayBubbleView::Host. | 623 // Overridden from TrayBubbleView::Host. |
631 virtual void BubbleViewDestroyed() OVERRIDE { | 624 virtual void BubbleViewDestroyed() OVERRIDE { |
632 bubble_view_ = NULL; | 625 bubble_view_ = NULL; |
633 contents_view_ = NULL; | 626 contents_view_ = NULL; |
634 } | 627 } |
635 | 628 |
636 virtual gfx::Rect GetAnchorRect() const OVERRIDE { | |
637 gfx::Rect anchor_rect = tray_->tray_container()->GetBoundsInScreen(); | |
638 return anchor_rect; | |
639 } | |
640 | |
641 virtual void OnMouseEnteredView() OVERRIDE { | 629 virtual void OnMouseEnteredView() OVERRIDE { |
642 } | 630 } |
643 | 631 |
644 virtual void OnMouseExitedView() OVERRIDE { | 632 virtual void OnMouseExitedView() OVERRIDE { |
645 } | 633 } |
646 | 634 |
647 virtual void OnClickedOutsideView() OVERRIDE { | 635 virtual void OnClickedOutsideView() OVERRIDE { |
648 // May delete |this|. | 636 // May delete |this|. |
649 tray_->status_area_widget()->HideWebNotificationBubble(); | 637 tray_->status_area_widget()->HideWebNotificationBubble(); |
650 } | 638 } |
651 | 639 |
652 // Overridden from views::Widget::Observer. | 640 // Overridden from views::Widget::Observer. |
653 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE { | 641 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE { |
654 CHECK_EQ(bubble_widget_, widget); | 642 CHECK_EQ(bubble_widget_, widget); |
655 bubble_widget_ = NULL; | 643 bubble_widget_ = NULL; |
656 tray_->HideBubble(); // Will destroy |this|. | 644 tray_->HideBubble(); // Will destroy |this|. |
657 } | 645 } |
658 | 646 |
659 private: | 647 private: |
660 void UpdateBubbleView() { | 648 void UpdateBubbleView() { |
661 contents_view_->Update(tray_->notification_list()->notifications()); | 649 contents_view_->Update(tray_->notification_list()->notifications()); |
662 bubble_view_->Show(); | 650 bubble_view_->Show(); |
663 } | 651 } |
664 | 652 |
665 WebNotificationTray* tray_; | 653 WebNotificationTray* tray_; |
666 internal::TrayBubbleView* bubble_view_; | 654 TrayBubbleView* bubble_view_; |
667 views::Widget* bubble_widget_; | 655 views::Widget* bubble_widget_; |
668 BubbleContentsView* contents_view_; | 656 BubbleContentsView* contents_view_; |
669 base::WeakPtrFactory<Bubble> weak_ptr_factory_; | 657 base::WeakPtrFactory<Bubble> weak_ptr_factory_; |
670 | 658 |
671 DISALLOW_COPY_AND_ASSIGN(Bubble); | 659 DISALLOW_COPY_AND_ASSIGN(Bubble); |
672 }; | 660 }; |
673 | 661 |
674 WebNotificationTray::WebNotificationTray( | 662 WebNotificationTray::WebNotificationTray( |
675 internal::StatusAreaWidget* status_area_widget) | 663 internal::StatusAreaWidget* status_area_widget) |
676 : status_area_widget_(status_area_widget), | 664 : status_area_widget_(status_area_widget), |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 } | 799 } |
812 | 800 |
813 void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) { | 801 void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) { |
814 internal::TrayBackgroundView::SetShelfAlignment(alignment); | 802 internal::TrayBackgroundView::SetShelfAlignment(alignment); |
815 SetTrayContainerBorder(); | 803 SetTrayContainerBorder(); |
816 SetBorder(); | 804 SetBorder(); |
817 tray_container_->SetLayoutManager(new views::BoxLayout( | 805 tray_container_->SetLayoutManager(new views::BoxLayout( |
818 alignment == SHELF_ALIGNMENT_BOTTOM ? | 806 alignment == SHELF_ALIGNMENT_BOTTOM ? |
819 views::BoxLayout::kHorizontal : views::BoxLayout::kVertical, | 807 views::BoxLayout::kHorizontal : views::BoxLayout::kVertical, |
820 0, 0, 0)); | 808 0, 0, 0)); |
| 809 // Destroy any existing bubble so that it will be rebuilt correctly. |
| 810 bubble_.reset(); |
821 } | 811 } |
822 | 812 |
823 bool WebNotificationTray::PerformAction(const views::Event& event) { | 813 bool WebNotificationTray::PerformAction(const views::Event& event) { |
824 if (bubble()) { | 814 if (bubble()) { |
825 status_area_widget_->HideWebNotificationBubble(); | 815 status_area_widget_->HideWebNotificationBubble(); |
826 } else { | 816 } else { |
827 status_area_widget_->ShowWebNotificationBubble( | 817 status_area_widget_->ShowWebNotificationBubble( |
828 internal::StatusAreaWidget::USER_ACTION); | 818 internal::StatusAreaWidget::USER_ACTION); |
829 } | 819 } |
830 return true; | 820 return true; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 UpdateIcon(); | 878 UpdateIcon(); |
889 if (!bubble()) | 879 if (!bubble()) |
890 return; | 880 return; |
891 if (GetNotificationCount() == 0) | 881 if (GetNotificationCount() == 0) |
892 status_area_widget_->HideWebNotificationBubble(); | 882 status_area_widget_->HideWebNotificationBubble(); |
893 else | 883 else |
894 bubble_->ScheduleUpdate(); | 884 bubble_->ScheduleUpdate(); |
895 } | 885 } |
896 | 886 |
897 } // namespace ash | 887 } // namespace ash |
OLD | NEW |