| 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 25 matching lines...) Expand all Loading... |
| 36 const int kTrayContainerVerticalPaddingVerticalAlignment = 1; | 36 const int kTrayContainerVerticalPaddingVerticalAlignment = 1; |
| 37 const int kTrayContainerHorizontalPaddingVerticalAlignment = 0; | 37 const int kTrayContainerHorizontalPaddingVerticalAlignment = 0; |
| 38 const int kPaddingFromLeftEdgeOfSystemTrayBottomAlignment = 8; | 38 const int kPaddingFromLeftEdgeOfSystemTrayBottomAlignment = 8; |
| 39 const int kPaddingFromTopEdgeOfSystemTrayVerticalAlignment = 10; | 39 const int kPaddingFromTopEdgeOfSystemTrayVerticalAlignment = 10; |
| 40 const int kNotificationImageIconWidth = 40; | 40 const int kNotificationImageIconWidth = 40; |
| 41 const int kNotificationImageIconHeight = 25; | 41 const int kNotificationImageIconHeight = 25; |
| 42 const int kNotificationImageIconInset = 4; | 42 const int kNotificationImageIconInset = 4; |
| 43 | 43 |
| 44 // Web Notification Bubble constants | 44 // Web Notification Bubble constants |
| 45 const int kWebNotificationBubbleMinHeight = 80; | 45 const int kWebNotificationBubbleMinHeight = 80; |
| 46 const int kWebNotificationBubbleMaxHeight = 400; | 46 const int kWebNotificationBubbleMaxHeight = 480; |
| 47 // Delay laying out the Bubble until all notifications have been added and icons | 47 // Delay laying out the Bubble until all notifications have been added and icons |
| 48 // have had a chance to load. | 48 // have had a chance to load. |
| 49 const int kUpdateDelayMs = 50; | 49 const int kUpdateDelayMs = 50; |
| 50 // Limit the number of visible notifications. | 50 // Limit the number of visible notifications. |
| 51 const int kMaxVisibleNotifications = 100; | 51 const int kMaxVisibleNotifications = 100; |
| 52 | 52 |
| 53 // Individual notifications constants | 53 // Individual notifications constants |
| 54 const int kWebNotificationWidth = 400; | 54 const int kWebNotificationWidth = 320; |
| 55 const int kWebNotificationButtonWidth = 32; | 55 const int kWebNotificationButtonWidth = 32; |
| 56 const int kWebNotificationIconSize = 40; | 56 const int kWebNotificationIconSize = 40; |
| 57 | 57 |
| 58 // Menu constants | 58 // Menu constants |
| 59 const int kTogglePermissionCommand = 0; | 59 const int kTogglePermissionCommand = 0; |
| 60 const int kToggleExtensionCommand = 1; | 60 const int kToggleExtensionCommand = 1; |
| 61 const int kShowSettingsCommand = 2; | 61 const int kShowSettingsCommand = 2; |
| 62 | 62 |
| 63 // The image has three icons: 1 notifiaction, 2 notifications, and 3+. | 63 // The image has three icons: 1 notifiaction, 2 notifications, and 3+. |
| 64 gfx::ImageSkia GetNotificationImage(int notification_count) { | 64 gfx::ImageSkia GetNotificationImage(int notification_count) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 const string16& display_source, | 117 const string16& display_source, |
| 118 const std::string& extension_id) { | 118 const std::string& extension_id) { |
| 119 Notifications::iterator iter = GetNotification(id); | 119 Notifications::iterator iter = GetNotification(id); |
| 120 if (iter != notifications_.end()) { | 120 if (iter != notifications_.end()) { |
| 121 // Update existing notification. | 121 // Update existing notification. |
| 122 iter->title = title; | 122 iter->title = title; |
| 123 iter->message = message; | 123 iter->message = message; |
| 124 iter->display_source = display_source; | 124 iter->display_source = display_source; |
| 125 iter->extension_id = extension_id; | 125 iter->extension_id = extension_id; |
| 126 } else { | 126 } else { |
| 127 notifications_.push_back( | 127 notifications_.push_front( |
| 128 WebNotification(id, title, message, display_source, extension_id)); | 128 WebNotification(id, title, message, display_source, extension_id)); |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 | 131 |
| 132 void UpdateNotificationMessage(const std::string& id, | 132 void UpdateNotificationMessage(const std::string& id, |
| 133 const string16& title, | 133 const string16& title, |
| 134 const string16& message) { | 134 const string16& message) { |
| 135 Notifications::iterator iter = GetNotification(id); | 135 Notifications::iterator iter = GetNotification(id); |
| 136 if (iter == notifications_.end()) | 136 if (iter == notifications_.end()) |
| 137 return; | 137 return; |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 !notification.display_source.empty()) { | 335 !notification.display_source.empty()) { |
| 336 menu_button_ = new views::MenuButton(NULL, string16(), this, true); | 336 menu_button_ = new views::MenuButton(NULL, string16(), this, true); |
| 337 menu_button_->set_border(views::Border::CreateEmptyBorder(0, 0, 0, 2)); | 337 menu_button_->set_border(views::Border::CreateEmptyBorder(0, 0, 0, 2)); |
| 338 } | 338 } |
| 339 | 339 |
| 340 views::GridLayout* layout = new views::GridLayout(this); | 340 views::GridLayout* layout = new views::GridLayout(this); |
| 341 SetLayoutManager(layout); | 341 SetLayoutManager(layout); |
| 342 | 342 |
| 343 views::ColumnSet* columns = layout->AddColumnSet(0); | 343 views::ColumnSet* columns = layout->AddColumnSet(0); |
| 344 | 344 |
| 345 columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2); | 345 int padding_width = kTrayPopupPaddingHorizontal/2; |
| 346 columns->AddPaddingColumn(0, padding_width); |
| 346 | 347 |
| 347 // Notification Icon. | 348 // Notification Icon. |
| 348 columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING, | 349 columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING, |
| 349 0, /* resize percent */ | 350 0, /* resize percent */ |
| 350 views::GridLayout::FIXED, | 351 views::GridLayout::FIXED, |
| 351 kWebNotificationIconSize, kWebNotificationIconSize); | 352 kWebNotificationIconSize, kWebNotificationIconSize); |
| 352 | 353 |
| 353 columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2); | 354 columns->AddPaddingColumn(0, padding_width); |
| 354 | 355 |
| 355 // Notification message text. | 356 // Notification message text. |
| 357 int message_width = kWebNotificationWidth - kWebNotificationIconSize - |
| 358 kWebNotificationButtonWidth - (padding_width * 3); |
| 356 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING, | 359 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING, |
| 357 100, /* resize percent */ | 360 100, /* resize percent */ |
| 358 views::GridLayout::USE_PREF, 0, 0); | 361 views::GridLayout::FIXED, message_width, message_width); |
| 359 | 362 |
| 360 columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2); | 363 columns->AddPaddingColumn(0, padding_width); |
| 361 | 364 |
| 362 // Close and menu buttons. | 365 // Close and menu buttons. |
| 363 columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING, | 366 columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING, |
| 364 0, /* resize percent */ | 367 0, /* resize percent */ |
| 365 views::GridLayout::FIXED, | 368 views::GridLayout::FIXED, |
| 366 kWebNotificationButtonWidth, | 369 kWebNotificationButtonWidth, |
| 367 kWebNotificationButtonWidth); | 370 kWebNotificationButtonWidth); |
| 368 | 371 |
| 369 // Layout rows | 372 // Layout rows |
| 370 layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems); | 373 layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 set_border(views::Border::CreateSolidSidedBorder( | 495 set_border(views::Border::CreateSolidSidedBorder( |
| 493 1, 1, 1, 1, ash::kBorderDarkColor)); | 496 1, 1, 1, 1, ash::kBorderDarkColor)); |
| 494 | 497 |
| 495 SetLayoutManager( | 498 SetLayoutManager( |
| 496 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); | 499 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); |
| 497 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); | 500 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); |
| 498 | 501 |
| 499 scroll_content_ = new views::View; | 502 scroll_content_ = new views::View; |
| 500 scroll_content_->SetLayoutManager( | 503 scroll_content_->SetLayoutManager( |
| 501 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); | 504 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); |
| 505 |
| 502 scroller_ = new internal::FixedSizedScrollView; | 506 scroller_ = new internal::FixedSizedScrollView; |
| 503 scroller_->SetContentsView(scroll_content_); | 507 scroller_->SetContentsView(scroll_content_); |
| 504 AddChildView(scroller_); | 508 AddChildView(scroller_); |
| 505 | 509 |
| 506 button_view_ = new internal::WebNotificationButtonView(tray); | 510 button_view_ = new internal::WebNotificationButtonView(tray); |
| 507 AddChildView(button_view_); | 511 AddChildView(button_view_); |
| 508 } | 512 } |
| 509 | 513 |
| 510 void Update(const WebNotificationList::Notifications& notifications) { | 514 void Update(const WebNotificationList::Notifications& notifications) { |
| 511 scroll_content_->RemoveAllChildViews(true); | 515 scroll_content_->RemoveAllChildViews(true); |
| 512 int num_children = notifications.size(); | 516 int num_children = 0; |
| 513 WebNotificationList::Notifications::const_iterator iter = | 517 for (WebNotificationList::Notifications::const_iterator iter = |
| 514 notifications.begin(); | 518 notifications.begin(); iter != notifications.end(); ++iter) { |
| 515 if (num_children > kMaxVisibleNotifications) { | |
| 516 std::advance(iter, num_children - kMaxVisibleNotifications); | |
| 517 num_children = kMaxVisibleNotifications; | |
| 518 } | |
| 519 for (; iter != notifications.end(); ++iter) { | |
| 520 WebNotificationView* view = new WebNotificationView(tray_, *iter); | 519 WebNotificationView* view = new WebNotificationView(tray_, *iter); |
| 521 scroll_content_->AddChildView(view); | 520 scroll_content_->AddChildView(view); |
| 521 if (++num_children >= kMaxVisibleNotifications) |
| 522 break; |
| 522 } | 523 } |
| 523 // Layout this first to set the preferred size of the scroller. | 524 SizeScrollContent(); |
| 524 PreferredSizeChanged(); | |
| 525 Layout(); | |
| 526 // Now layout the widget with this correctly sized. | |
| 527 PreferredSizeChanged(); | |
| 528 GetWidget()->GetRootView()->Layout(); | |
| 529 GetWidget()->GetRootView()->SchedulePaint(); | 525 GetWidget()->GetRootView()->SchedulePaint(); |
| 530 | |
| 531 // Scroll to show the most recent notification. | |
| 532 if (num_children > 0) { | |
| 533 scroll_content_->ScrollRectToVisible( | |
| 534 scroll_content_->child_at(num_children - 1)->bounds()); | |
| 535 } | |
| 536 } | |
| 537 | |
| 538 // Overridden from views::View: | |
| 539 virtual void Layout() OVERRIDE { | |
| 540 SizeScrollContent(); | |
| 541 views::View::Layout(); | |
| 542 } | 526 } |
| 543 | 527 |
| 544 private: | 528 private: |
| 545 void SizeScrollContent() { | 529 void SizeScrollContent() { |
| 546 gfx::Size scroll_size = scroll_content_->GetPreferredSize(); | 530 gfx::Size scroll_size = scroll_content_->GetPreferredSize(); |
| 547 int button_height = button_view_->GetPreferredSize().height(); | 531 int button_height = button_view_->GetPreferredSize().height(); |
| 548 int scroll_height = std::min( | 532 int scroll_height = std::min( |
| 549 std::max(scroll_size.height(), | 533 std::max(scroll_size.height(), |
| 550 kWebNotificationBubbleMinHeight - button_height), | 534 kWebNotificationBubbleMinHeight - button_height), |
| 551 kWebNotificationBubbleMaxHeight - button_height); | 535 kWebNotificationBubbleMaxHeight - button_height); |
| 552 if (scroll_height < scroll_size.height()) { | 536 scroll_size.set_height(scroll_height); |
| 553 scroll_size.set_height(scroll_height); | 537 scroller_->SetFixedSize(scroll_size); |
| 554 scroller_->SetFixedSize(scroll_size); | 538 scroller_->SizeToPreferredSize(); |
| 555 } else { | |
| 556 scroller_->SetFixedSize(gfx::Size()); | |
| 557 } | |
| 558 scroller_->InvalidateLayout(); | |
| 559 } | 539 } |
| 560 | 540 |
| 561 WebNotificationTray* tray_; | 541 WebNotificationTray* tray_; |
| 562 internal::FixedSizedScrollView* scroller_; | 542 internal::FixedSizedScrollView* scroller_; |
| 563 views::View* scroll_content_; | 543 views::View* scroll_content_; |
| 564 internal::WebNotificationButtonView* button_view_; | 544 internal::WebNotificationButtonView* button_view_; |
| 565 | 545 |
| 566 DISALLOW_COPY_AND_ASSIGN(BubbleContentsView); | 546 DISALLOW_COPY_AND_ASSIGN(BubbleContentsView); |
| 567 }; | 547 }; |
| 568 | 548 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE { | 632 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE { |
| 653 CHECK_EQ(bubble_widget_, widget); | 633 CHECK_EQ(bubble_widget_, widget); |
| 654 bubble_widget_ = NULL; | 634 bubble_widget_ = NULL; |
| 655 tray_->HideBubble(); // Will destroy |this|. | 635 tray_->HideBubble(); // Will destroy |this|. |
| 656 } | 636 } |
| 657 | 637 |
| 658 private: | 638 private: |
| 659 void UpdateBubbleView() { | 639 void UpdateBubbleView() { |
| 660 contents_view_->Update(tray_->notification_list()->notifications()); | 640 contents_view_->Update(tray_->notification_list()->notifications()); |
| 661 bubble_view_->Show(); | 641 bubble_view_->Show(); |
| 642 bubble_view_->UpdateBubble(); |
| 662 } | 643 } |
| 663 | 644 |
| 664 WebNotificationTray* tray_; | 645 WebNotificationTray* tray_; |
| 665 internal::TrayBubbleView* bubble_view_; | 646 internal::TrayBubbleView* bubble_view_; |
| 666 views::Widget* bubble_widget_; | 647 views::Widget* bubble_widget_; |
| 667 BubbleContentsView* contents_view_; | 648 BubbleContentsView* contents_view_; |
| 668 base::WeakPtrFactory<Bubble> weak_ptr_factory_; | 649 base::WeakPtrFactory<Bubble> weak_ptr_factory_; |
| 669 | 650 |
| 670 DISALLOW_COPY_AND_ASSIGN(Bubble); | 651 DISALLOW_COPY_AND_ASSIGN(Bubble); |
| 671 }; | 652 }; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 } | 791 } |
| 811 | 792 |
| 812 void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) { | 793 void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) { |
| 813 internal::TrayBackgroundView::SetShelfAlignment(alignment); | 794 internal::TrayBackgroundView::SetShelfAlignment(alignment); |
| 814 SetTrayContainerBorder(); | 795 SetTrayContainerBorder(); |
| 815 SetBorder(); | 796 SetBorder(); |
| 816 tray_container_->SetLayoutManager(new views::BoxLayout( | 797 tray_container_->SetLayoutManager(new views::BoxLayout( |
| 817 alignment == SHELF_ALIGNMENT_BOTTOM ? | 798 alignment == SHELF_ALIGNMENT_BOTTOM ? |
| 818 views::BoxLayout::kHorizontal : views::BoxLayout::kVertical, | 799 views::BoxLayout::kHorizontal : views::BoxLayout::kVertical, |
| 819 0, 0, 0)); | 800 0, 0, 0)); |
| 801 // Destroy any existing bubble so that it will be rebuilt correctly. |
| 802 bubble_.reset(); |
| 820 } | 803 } |
| 821 | 804 |
| 822 bool WebNotificationTray::PerformAction(const views::Event& event) { | 805 bool WebNotificationTray::PerformAction(const views::Event& event) { |
| 823 if (bubble()) { | 806 if (bubble()) { |
| 824 status_area_widget_->HideWebNotificationBubble(); | 807 status_area_widget_->HideWebNotificationBubble(); |
| 825 } else { | 808 } else { |
| 826 status_area_widget_->ShowWebNotificationBubble( | 809 status_area_widget_->ShowWebNotificationBubble( |
| 827 internal::StatusAreaWidget::USER_ACTION); | 810 internal::StatusAreaWidget::USER_ACTION); |
| 828 } | 811 } |
| 829 return true; | 812 return true; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 UpdateIcon(); | 870 UpdateIcon(); |
| 888 if (!bubble()) | 871 if (!bubble()) |
| 889 return; | 872 return; |
| 890 if (GetNotificationCount() == 0) | 873 if (GetNotificationCount() == 0) |
| 891 status_area_widget_->HideWebNotificationBubble(); | 874 status_area_widget_->HideWebNotificationBubble(); |
| 892 else | 875 else |
| 893 bubble_->ScheduleUpdate(); | 876 bubble_->ScheduleUpdate(); |
| 894 } | 877 } |
| 895 | 878 |
| 896 } // namespace ash | 879 } // namespace ash |
| OLD | NEW |