| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "ui/message_center/views/message_center_view.h" | 5 #include "ui/message_center/views/message_center_view.h" |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 int NoNotificationMessageView::GetHeightForWidth(int width) { | 152 int NoNotificationMessageView::GetHeightForWidth(int width) { |
| 153 return kMinScrollViewHeight; | 153 return kMinScrollViewHeight; |
| 154 } | 154 } |
| 155 | 155 |
| 156 void NoNotificationMessageView::Layout() { | 156 void NoNotificationMessageView::Layout() { |
| 157 int text_height = label_->GetHeightForWidth(width()); | 157 int text_height = label_->GetHeightForWidth(width()); |
| 158 int margin = (height() - text_height) / 2; | 158 int margin = (height() - text_height) / 2; |
| 159 label_->SetBounds(0, margin, width(), text_height); | 159 label_->SetBounds(0, margin, width(), text_height); |
| 160 } | 160 } |
| 161 | 161 |
| 162 // Displays a list of messages for rich notifications. It also supports | 162 // Displays a list of messages for rich notifications. Functions as an array of |
| 163 // MessageViews and animates them on transitions. It also supports |
| 163 // repositioning. | 164 // repositioning. |
| 164 class MessageListView : public views::View, | 165 class MessageListView : public views::View, |
| 165 public views::BoundsAnimatorObserver { | 166 public views::BoundsAnimatorObserver { |
| 166 public: | 167 public: |
| 167 explicit MessageListView(MessageCenterView* message_center_view, | 168 explicit MessageListView(MessageCenterView* message_center_view, |
| 168 bool top_down); | 169 bool top_down); |
| 169 virtual ~MessageListView(); | 170 virtual ~MessageListView(); |
| 170 | 171 |
| 171 void AddNotificationAt(views::View* view, int i); | 172 void AddNotificationAt(MessageView* view, int i); |
| 172 void RemoveNotificationAt(int i); | 173 void RemoveNotificationAt(int i); |
| 173 void UpdateNotificationAt(views::View* view, int i); | 174 void UpdateNotificationAt(MessageView* view, int i); |
| 174 void SetRepositionTarget(const gfx::Rect& target_rect); | 175 void SetRepositionTarget(const gfx::Rect& target_rect); |
| 175 void ResetRepositionSession(); | 176 void ResetRepositionSession(); |
| 176 void ClearAllNotifications(const gfx::Rect& visible_scroll_rect); | 177 void ClearAllNotifications(const gfx::Rect& visible_scroll_rect); |
| 177 | 178 |
| 178 protected: | 179 protected: |
| 179 // Overridden from views::View. | 180 // Overridden from views::View. |
| 180 virtual void Layout() OVERRIDE; | 181 virtual void Layout() OVERRIDE; |
| 181 virtual gfx::Size GetPreferredSize() OVERRIDE; | 182 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| 182 virtual int GetHeightForWidth(int width) OVERRIDE; | 183 virtual int GetHeightForWidth(int width) OVERRIDE; |
| 183 virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE; | 184 virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 for (int i = 0; i < child_count(); ++i) { | 279 for (int i = 0; i < child_count(); ++i) { |
| 279 views::View* child = child_at(i); | 280 views::View* child = child_at(i); |
| 280 if (!child->visible()) | 281 if (!child->visible()) |
| 281 continue; | 282 continue; |
| 282 int height = child->GetHeightForWidth(child_area.width()); | 283 int height = child->GetHeightForWidth(child_area.width()); |
| 283 child->SetBounds(child_area.x(), top, child_area.width(), height); | 284 child->SetBounds(child_area.x(), top, child_area.width(), height); |
| 284 top += height + between_items; | 285 top += height + between_items; |
| 285 } | 286 } |
| 286 } | 287 } |
| 287 | 288 |
| 288 void MessageListView::AddNotificationAt(views::View* view, int i) { | 289 void MessageListView::AddNotificationAt(MessageView* view, int i) { |
| 289 AddChildViewAt(view, GetActualIndex(i)); | 290 AddChildViewAt(view, GetActualIndex(i)); |
| 290 if (GetContentsBounds().IsEmpty()) | 291 if (GetContentsBounds().IsEmpty()) |
| 291 return; | 292 return; |
| 292 | 293 |
| 293 adding_views_.insert(view); | 294 adding_views_.insert(view); |
| 294 DoUpdateIfPossible(); | 295 DoUpdateIfPossible(); |
| 295 } | 296 } |
| 296 | 297 |
| 297 void MessageListView::RemoveNotificationAt(int i) { | 298 void MessageListView::RemoveNotificationAt(int i) { |
| 298 views::View* child = child_at(GetActualIndex(i)); | 299 views::View* child = child_at(GetActualIndex(i)); |
| 299 if (GetContentsBounds().IsEmpty()) { | 300 if (GetContentsBounds().IsEmpty()) { |
| 300 delete child; | 301 delete child; |
| 301 } else { | 302 } else { |
| 302 if (child->layer()) { | 303 if (child->layer()) { |
| 303 deleting_views_.insert(child); | 304 deleting_views_.insert(child); |
| 304 } else { | 305 } else { |
| 305 if (animator_.get()) | 306 if (animator_.get()) |
| 306 animator_->StopAnimatingView(child); | 307 animator_->StopAnimatingView(child); |
| 307 delete child; | 308 delete child; |
| 308 } | 309 } |
| 309 DoUpdateIfPossible(); | 310 DoUpdateIfPossible(); |
| 310 } | 311 } |
| 311 } | 312 } |
| 312 | 313 |
| 313 void MessageListView::UpdateNotificationAt(views::View* view, int i) { | 314 void MessageListView::UpdateNotificationAt(MessageView* view, int i) { |
| 314 int actual_index = GetActualIndex(i); | 315 int actual_index = GetActualIndex(i); |
| 315 views::View* child = child_at(actual_index); | 316 views::View* child = child_at(actual_index); |
| 316 if (animator_.get()) | 317 if (animator_.get()) |
| 317 animator_->StopAnimatingView(child); | 318 animator_->StopAnimatingView(child); |
| 318 gfx::Rect old_bounds = child->bounds(); | 319 gfx::Rect old_bounds = child->bounds(); |
| 319 if (deleting_views_.find(child) != deleting_views_.end()) | 320 if (deleting_views_.find(child) != deleting_views_.end()) |
| 320 deleting_views_.erase(child); | 321 deleting_views_.erase(child); |
| 321 if (deleted_when_done_.find(child) != deleted_when_done_.end()) | 322 if (deleted_when_done_.find(child) != deleted_when_done_.end()) |
| 322 deleted_when_done_.erase(child); | 323 deleted_when_done_.erase(child); |
| 323 delete child; | 324 delete child; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 MessageCenterView::~MessageCenterView() { | 657 MessageCenterView::~MessageCenterView() { |
| 657 if (!is_closing_) | 658 if (!is_closing_) |
| 658 message_center_->RemoveObserver(this); | 659 message_center_->RemoveObserver(this); |
| 659 } | 660 } |
| 660 | 661 |
| 661 void MessageCenterView::SetNotifications( | 662 void MessageCenterView::SetNotifications( |
| 662 const NotificationList::Notifications& notifications) { | 663 const NotificationList::Notifications& notifications) { |
| 663 if (is_closing_) | 664 if (is_closing_) |
| 664 return; | 665 return; |
| 665 | 666 |
| 666 message_views_.clear(); | 667 notification_views_.clear(); |
| 667 int index = 0; | 668 int index = 0; |
| 668 for (NotificationList::Notifications::const_iterator iter = | 669 for (NotificationList::Notifications::const_iterator iter = |
| 669 notifications.begin(); iter != notifications.end(); | 670 notifications.begin(); iter != notifications.end(); |
| 670 ++iter, ++index) { | 671 ++iter, ++index) { |
| 671 AddNotificationAt(*(*iter), index); | 672 AddNotificationAt(*(*iter), index); |
| 672 if (message_views_.size() >= kMaxVisibleMessageCenterNotifications) | 673 if (notification_views_.size() >= kMaxVisibleMessageCenterNotifications) |
| 673 break; | 674 break; |
| 674 } | 675 } |
| 675 NotificationsChanged(); | 676 NotificationsChanged(); |
| 676 scroller_->RequestFocus(); | 677 scroller_->RequestFocus(); |
| 677 } | 678 } |
| 678 | 679 |
| 679 void MessageCenterView::SetSettingsVisible(bool visible) { | 680 void MessageCenterView::SetSettingsVisible(bool visible) { |
| 680 if (is_closing_) | 681 if (is_closing_) |
| 681 return; | 682 return; |
| 682 | 683 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 int index = 0; | 873 int index = 0; |
| 873 const NotificationList::Notifications& notifications = | 874 const NotificationList::Notifications& notifications = |
| 874 message_center_->GetVisibleNotifications(); | 875 message_center_->GetVisibleNotifications(); |
| 875 for (NotificationList::Notifications::const_iterator iter = | 876 for (NotificationList::Notifications::const_iterator iter = |
| 876 notifications.begin(); iter != notifications.end(); | 877 notifications.begin(); iter != notifications.end(); |
| 877 ++iter, ++index) { | 878 ++iter, ++index) { |
| 878 if ((*iter)->id() == id) { | 879 if ((*iter)->id() == id) { |
| 879 AddNotificationAt(*(*iter), index); | 880 AddNotificationAt(*(*iter), index); |
| 880 break; | 881 break; |
| 881 } | 882 } |
| 882 if (message_views_.size() >= kMaxVisibleMessageCenterNotifications) | 883 if (notification_views_.size() >= kMaxVisibleMessageCenterNotifications) |
| 883 break; | 884 break; |
| 884 } | 885 } |
| 885 NotificationsChanged(); | 886 NotificationsChanged(); |
| 886 } | 887 } |
| 887 | 888 |
| 888 void MessageCenterView::OnNotificationRemoved(const std::string& id, | 889 void MessageCenterView::OnNotificationRemoved(const std::string& id, |
| 889 bool by_user) { | 890 bool by_user) { |
| 890 for (size_t i = 0; i < message_views_.size(); ++i) { | 891 NotificationViewsMap::iterator view_iter = notification_views_.find(id); |
| 891 if (message_views_[i]->notification_id() == id) { | 892 if (view_iter == notification_views_.end()) |
| 892 if (by_user) { | 893 return; |
| 893 message_list_view_->SetRepositionTarget(message_views_[i]->bounds()); | 894 NotificationView* view = view_iter->second; |
| 894 // Moves the keyboard focus to the next notification if the removed | 895 int index = message_list_view_->GetIndexOf(view); |
| 895 // notification is focused so that the user can dismiss notifications | 896 if (by_user) { |
| 896 // without re-focusing by tab key. | 897 message_list_view_->SetRepositionTarget(view->bounds()); |
| 897 if (message_views_.size() > 1) { | 898 // Moves the keyboard focus to the next notification if the removed |
| 898 views::View* focused_view = GetFocusManager()->GetFocusedView(); | 899 // notification is focused so that the user can dismiss notifications |
| 899 if (message_views_[i]->IsCloseButtonFocused() || | 900 // without re-focusing by tab key. |
| 900 focused_view == message_views_[i]) { | 901 if (view->IsCloseButtonFocused() || |
| 901 size_t next_index = i + 1; | 902 view == GetFocusManager()->GetFocusedView()) { |
| 902 if (next_index >= message_views_.size()) | 903 views::View* next_focused_view = NULL; |
| 903 next_index = message_views_.size() - 2; | 904 if (message_list_view_->child_count() > index + 1) |
| 904 if (focused_view == message_views_[i]) | 905 next_focused_view = message_list_view_->child_at(index + 1); |
| 905 message_views_[next_index]->RequestFocus(); | 906 else if (index > 0) |
| 906 else | 907 next_focused_view = message_list_view_->child_at(index - 1); |
| 907 message_views_[next_index]->RequestFocusOnCloseButton(); | 908 |
| 908 } | 909 if (next_focused_view) { |
| 909 } | 910 if (view->IsCloseButtonFocused()) |
| 911 // Safe cast since all views in MessageListView are MessageViews. |
| 912 static_cast<MessageView*>( |
| 913 next_focused_view)->RequestFocusOnCloseButton(); |
| 914 else |
| 915 next_focused_view->RequestFocus(); |
| 910 } | 916 } |
| 911 message_list_view_->RemoveNotificationAt(i); | |
| 912 message_views_.erase(message_views_.begin() + i); | |
| 913 NotificationsChanged(); | |
| 914 break; | |
| 915 } | 917 } |
| 916 } | 918 } |
| 919 message_list_view_->RemoveNotificationAt(index); |
| 920 notification_views_.erase(view_iter); |
| 921 NotificationsChanged(); |
| 917 } | 922 } |
| 918 | 923 |
| 919 void MessageCenterView::OnNotificationUpdated(const std::string& id) { | 924 void MessageCenterView::OnNotificationUpdated(const std::string& id) { |
| 925 NotificationViewsMap::const_iterator view_iter = notification_views_.find(id); |
| 926 if (view_iter == notification_views_.end()) |
| 927 return; |
| 928 NotificationView* view = view_iter->second; |
| 929 size_t index = message_list_view_->GetIndexOf(view); |
| 930 DCHECK(index >= 0); |
| 931 // TODO(dimich): add MessageCenter::GetVisibleNotificationById(id) |
| 920 const NotificationList::Notifications& notifications = | 932 const NotificationList::Notifications& notifications = |
| 921 message_center_->GetVisibleNotifications(); | 933 message_center_->GetVisibleNotifications(); |
| 922 size_t index = 0; | |
| 923 for (NotificationList::Notifications::const_iterator iter = | 934 for (NotificationList::Notifications::const_iterator iter = |
| 924 notifications.begin(); | 935 notifications.begin(); iter != notifications.end(); ++iter) { |
| 925 iter != notifications.end() && index < message_views_.size(); | |
| 926 ++iter, ++index) { | |
| 927 DCHECK((*iter)->id() == message_views_[index]->notification_id()); | |
| 928 if ((*iter)->id() == id) { | 936 if ((*iter)->id() == id) { |
| 929 bool expanded = true; | 937 bool expanded = true; |
| 930 if (IsExperimentalNotificationUIEnabled()) | 938 if (IsExperimentalNotificationUIEnabled()) |
| 931 expanded = (*iter)->is_expanded(); | 939 expanded = (*iter)->is_expanded(); |
| 932 MessageView* view = | 940 NotificationView* view = |
| 933 NotificationView::Create(*(*iter), | 941 NotificationView::Create(*(*iter), |
| 934 message_center_, | 942 message_center_, |
| 935 tray_, | 943 tray_, |
| 936 expanded, | 944 expanded, |
| 937 false); // Not creating a top-level | 945 false); // Not creating a top-level |
| 938 // notification. | 946 // notification. |
| 939 view->set_scroller(scroller_); | 947 view->set_scroller(scroller_); |
| 940 message_list_view_->UpdateNotificationAt(view, index); | 948 message_list_view_->UpdateNotificationAt(view, index); |
| 941 message_views_[index] = view; | 949 notification_views_[id] = view; |
| 942 NotificationsChanged(); | 950 NotificationsChanged(); |
| 943 break; | 951 break; |
| 944 } | 952 } |
| 945 } | 953 } |
| 946 } | 954 } |
| 947 | 955 |
| 948 void MessageCenterView::AnimationEnded(const gfx::Animation* animation) { | 956 void MessageCenterView::AnimationEnded(const gfx::Animation* animation) { |
| 949 DCHECK_EQ(animation, settings_transition_animation_.get()); | 957 DCHECK_EQ(animation, settings_transition_animation_.get()); |
| 950 | 958 |
| 951 Visibility visibility = target_view_ == settings_view_ | 959 Visibility visibility = target_view_ == settings_view_ |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 AnimationEnded(animation); | 993 AnimationEnded(animation); |
| 986 } | 994 } |
| 987 | 995 |
| 988 void MessageCenterView::AddNotificationAt(const Notification& notification, | 996 void MessageCenterView::AddNotificationAt(const Notification& notification, |
| 989 int index) { | 997 int index) { |
| 990 // NotificationViews are expanded by default here until | 998 // NotificationViews are expanded by default here until |
| 991 // http://crbug.com/217902 is fixed. TODO(dharcourt): Fix. | 999 // http://crbug.com/217902 is fixed. TODO(dharcourt): Fix. |
| 992 bool expanded = true; | 1000 bool expanded = true; |
| 993 if (IsExperimentalNotificationUIEnabled()) | 1001 if (IsExperimentalNotificationUIEnabled()) |
| 994 expanded = notification.is_expanded(); | 1002 expanded = notification.is_expanded(); |
| 995 MessageView* view = | 1003 NotificationView* view = |
| 996 NotificationView::Create(notification, | 1004 NotificationView::Create(notification, |
| 997 message_center_, | 1005 message_center_, |
| 998 tray_, | 1006 tray_, |
| 999 expanded, | 1007 expanded, |
| 1000 false); // Not creating a top-level | 1008 false); // Not creating a top-level |
| 1001 // notification. | 1009 // notification. |
| 1002 view->set_scroller(scroller_); | 1010 view->set_scroller(scroller_); |
| 1003 message_views_.insert(message_views_.begin() + index, view); | 1011 notification_views_[notification.id()] = view; |
| 1004 message_list_view_->AddNotificationAt(view, index); | 1012 message_list_view_->AddNotificationAt(view, index); |
| 1005 message_center_->DisplayedNotification(notification.id()); | 1013 message_center_->DisplayedNotification(notification.id()); |
| 1006 } | 1014 } |
| 1007 | 1015 |
| 1008 void MessageCenterView::NotificationsChanged() { | 1016 void MessageCenterView::NotificationsChanged() { |
| 1009 bool no_message_views = message_views_.empty(); | 1017 bool no_message_views = notification_views_.empty(); |
| 1010 // All the children of this view are owned by |this|. | 1018 // All the children of this view are owned by |this|. |
| 1011 scroller_->contents()->RemoveAllChildViews(/*delete_children=*/false); | 1019 scroller_->contents()->RemoveAllChildViews(/*delete_children=*/false); |
| 1012 scroller_->contents()->AddChildView( | 1020 scroller_->contents()->AddChildView( |
| 1013 no_message_views ? empty_list_view_.get() : message_list_view_.get()); | 1021 no_message_views ? empty_list_view_.get() : message_list_view_.get()); |
| 1014 | 1022 |
| 1015 button_bar_->SetCloseAllButtonEnabled(!no_message_views); | 1023 button_bar_->SetCloseAllButtonEnabled(!no_message_views); |
| 1016 scroller_->set_focusable(!no_message_views); | 1024 scroller_->set_focusable(!no_message_views); |
| 1017 | 1025 |
| 1018 scroller_->InvalidateLayout(); | 1026 scroller_->InvalidateLayout(); |
| 1019 PreferredSizeChanged(); | 1027 PreferredSizeChanged(); |
| 1020 Layout(); | 1028 Layout(); |
| 1021 } | 1029 } |
| 1022 | 1030 |
| 1023 void MessageCenterView::SetNotificationViewForTest(views::View* view) { | 1031 void MessageCenterView::SetNotificationViewForTest(MessageView* view) { |
| 1024 message_list_view_->AddNotificationAt(view, 0); | 1032 message_list_view_->AddNotificationAt(view, 0); |
| 1025 } | 1033 } |
| 1026 | 1034 |
| 1027 } // namespace message_center | 1035 } // namespace message_center |
| OLD | NEW |