Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ui / message_center / views / message_center_view.cc
index 7d8da4a..8e5b4d2 100644 (file)
@@ -25,6 +25,7 @@
 #include "ui/message_center/message_center_tray.h"
 #include "ui/message_center/message_center_types.h"
 #include "ui/message_center/message_center_util.h"
+#include "ui/message_center/views/bounded_scroll_view.h"
 #include "ui/message_center/views/message_center_button_bar.h"
 #include "ui/message_center/views/message_view.h"
 #include "ui/message_center/views/message_view_context_menu_controller.h"
@@ -36,8 +37,6 @@
 #include "ui/views/border.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/label.h"
-#include "ui/views/controls/scroll_view.h"
-#include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/widget/widget.h"
@@ -51,69 +50,11 @@ const SkColor kNoNotificationsTextColor = SkColorSetRGB(0xb4, 0xb4, 0xb4);
 const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0);
 #endif
 const int kAnimateClearingNextNotificationDelayMS = 40;
-const int kMinScrollViewHeight = 100;
 
 const int kDefaultAnimationDurationMs = 120;
 const int kDefaultFrameRateHz = 60;
 }  // namespace
 
-// BoundedScrollView ///////////////////////////////////////////////////////////
-
-// A custom scroll view whose height has a minimum and maximum value and whose
-// scroll bar disappears when not needed.
-class BoundedScrollView : public views::ScrollView {
- public:
-  BoundedScrollView(int min_height, int max_height);
-
-  // Overridden from views::View:
-  virtual gfx::Size GetPreferredSize() OVERRIDE;
-  virtual int GetHeightForWidth(int width) OVERRIDE;
-  virtual void Layout() OVERRIDE;
-
- private:
-  int min_height_;
-  int max_height_;
-
-  DISALLOW_COPY_AND_ASSIGN(BoundedScrollView);
-};
-
-BoundedScrollView::BoundedScrollView(int min_height, int max_height)
-    : min_height_(min_height),
-      max_height_(max_height) {
-  set_notify_enter_exit_on_child(true);
-  set_background(
-      views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
-  SetVerticalScrollBar(new views::OverlayScrollBar(false));
-}
-
-gfx::Size BoundedScrollView::GetPreferredSize() {
-  gfx::Size size = contents()->GetPreferredSize();
-  size.SetToMax(gfx::Size(size.width(), min_height_));
-  size.SetToMin(gfx::Size(size.width(), max_height_));
-  gfx::Insets insets = GetInsets();
-  size.Enlarge(insets.width(), insets.height());
-  return size;
-}
-
-int BoundedScrollView::GetHeightForWidth(int width) {
-  gfx::Insets insets = GetInsets();
-  width = std::max(0, width - insets.width());
-  int height = contents()->GetHeightForWidth(width) + insets.height();
-  return std::min(std::max(height, min_height_), max_height_);
-}
-
-void BoundedScrollView::Layout() {
-  int content_width = width();
-  int content_height = contents()->GetHeightForWidth(content_width);
-  if (content_height > height()) {
-    content_width = std::max(content_width - GetScrollBarWidth(), 0);
-    content_height = contents()->GetHeightForWidth(content_width);
-  }
-  if (contents()->bounds().size() != gfx::Size(content_width, content_height))
-    contents()->SetBounds(0, 0, content_width, content_height);
-  views::ScrollView::Layout();
-}
-
 class NoNotificationMessageView : public views::View {
  public:
   NoNotificationMessageView();
@@ -171,8 +112,8 @@ class MessageListView : public views::View,
   virtual ~MessageListView();
 
   void AddNotificationAt(MessageView* view, int i);
-  void RemoveNotificationAt(int i);
-  void UpdateNotificationAt(MessageView* view, int i);
+  void RemoveNotification(MessageView* view);
+  void UpdateNotification(MessageView* view, MessageView* new_view);
   void SetRepositionTarget(const gfx::Rect& target_rect);
   void ResetRepositionSession();
   void ClearAllNotifications(const gfx::Rect& visible_scroll_rect);
@@ -191,13 +132,6 @@ class MessageListView : public views::View,
   virtual void OnBoundsAnimatorDone(views::BoundsAnimator* animator) OVERRIDE;
 
  private:
-  // Returns the actual index for child of |index|.
-  // MessageListView allows to slide down upper notifications, which means
-  // that the upper ones should come above the lower ones if top_down is not
-  // enabled. To achieve this, inversed order is adopted. The top most
-  // notification is the last child, and the bottom most notification is the
-  // first child.
-  int GetActualIndex(int index);
   bool IsValidChild(views::View* child);
   void DoUpdateIfPossible();
 
@@ -287,8 +221,22 @@ void MessageListView::Layout() {
   }
 }
 
-void MessageListView::AddNotificationAt(MessageView* view, int i) {
-  AddChildViewAt(view, GetActualIndex(i));
+void MessageListView::AddNotificationAt(MessageView* view, int index) {
+  // |index| refers to a position in a subset of valid children. |real_index|
+  // in a list includes the invalid children, so we compute the real index by
+  // walking the list until |index| number of valid children are encountered,
+  // or to the end of the list.
+  int real_index = 0;
+  while (real_index < child_count()) {
+    if (IsValidChild(child_at(real_index))) {
+      --index;
+      if (index < 0)
+        break;
+    }
+    ++real_index;
+  }
+
+  AddChildViewAt(view, real_index);
   if (GetContentsBounds().IsEmpty())
     return;
 
@@ -296,36 +244,40 @@ void MessageListView::AddNotificationAt(MessageView* view, int i) {
   DoUpdateIfPossible();
 }
 
-void MessageListView::RemoveNotificationAt(int i) {
-  views::View* child = child_at(GetActualIndex(i));
+void MessageListView::RemoveNotification(MessageView* view) {
+  DCHECK_EQ(view->parent(), this);
   if (GetContentsBounds().IsEmpty()) {
-    delete child;
+    delete view;
   } else {
-    if (child->layer()) {
-      deleting_views_.insert(child);
+    if (view->layer()) {
+      deleting_views_.insert(view);
     } else {
       if (animator_.get())
-        animator_->StopAnimatingView(child);
-      delete child;
+        animator_->StopAnimatingView(view);
+      delete view;
     }
     DoUpdateIfPossible();
   }
 }
 
-void MessageListView::UpdateNotificationAt(MessageView* view, int i) {
-  int actual_index = GetActualIndex(i);
-  views::View* child = child_at(actual_index);
+void MessageListView::UpdateNotification(MessageView* view,
+                                         MessageView* new_view) {
+  int index = GetIndexOf(view);
+  DCHECK_LE(0, index);  // GetIndexOf is negative if not a child.
+
   if (animator_.get())
-    animator_->StopAnimatingView(child);
-  gfx::Rect old_bounds = child->bounds();
-  if (deleting_views_.find(child) != deleting_views_.end())
-    deleting_views_.erase(child);
-  if (deleted_when_done_.find(child) != deleted_when_done_.end())
-    deleted_when_done_.erase(child);
-  delete child;
-  AddChildViewAt(view, actual_index);
-  view->SetBounds(old_bounds.x(), old_bounds.y(), old_bounds.width(),
-                  view->GetHeightForWidth(old_bounds.width()));
+    animator_->StopAnimatingView(view);
+  gfx::Rect old_bounds = view->bounds();
+  if (deleting_views_.find(view) != deleting_views_.end())
+    deleting_views_.erase(view);
+  if (deleted_when_done_.find(view) != deleted_when_done_.end())
+    deleted_when_done_.erase(view);
+  delete view;
+  AddChildViewAt(new_view, index);
+  new_view->SetBounds(old_bounds.x(),
+                      old_bounds.y(),
+                      old_bounds.width(),
+                      new_view->GetHeightForWidth(old_bounds.width()));
   DoUpdateIfPossible();
 }
 
@@ -443,12 +395,6 @@ void MessageListView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) {
     GetWidget()->SynthesizeMouseMoveEvent();
 }
 
-int MessageListView::GetActualIndex(int index) {
-  for (int i = 0; i < child_count() && i <= index; ++i)
-    index += IsValidChild(child_at(i)) ? 0 : 1;
-  return std::min(index, child_count());
-}
-
 bool MessageListView::IsValidChild(views::View* child) {
   return child->visible() &&
          deleting_views_.find(child) == deleting_views_.end() &&
@@ -898,6 +844,7 @@ void MessageCenterView::OnNotificationRemoved(const std::string& id,
     return;
   NotificationView* view = view_iter->second;
   int index = message_list_view_->GetIndexOf(view);
+  DCHECK_LE(0, index);
   if (by_user) {
     message_list_view_->SetRepositionTarget(view->bounds());
     // Moves the keyboard focus to the next notification if the removed
@@ -921,7 +868,7 @@ void MessageCenterView::OnNotificationRemoved(const std::string& id,
       }
     }
   }
-  message_list_view_->RemoveNotificationAt(index);
+  message_list_view_->RemoveNotification(view);
   notification_views_.erase(view_iter);
   NotificationsChanged();
 }
@@ -931,27 +878,21 @@ void MessageCenterView::OnNotificationUpdated(const std::string& id) {
   if (view_iter == notification_views_.end())
     return;
   NotificationView* view = view_iter->second;
-  size_t index = message_list_view_->GetIndexOf(view);
-  DCHECK(index >= 0);
   // TODO(dimich): add MessageCenter::GetVisibleNotificationById(id)
   const NotificationList::Notifications& notifications =
       message_center_->GetVisibleNotifications();
   for (NotificationList::Notifications::const_iterator iter =
            notifications.begin(); iter != notifications.end(); ++iter) {
     if ((*iter)->id() == id) {
-      bool expanded = true;
-      if (IsExperimentalNotificationUIEnabled())
-        expanded = (*iter)->is_expanded();
-      NotificationView* view =
+      NotificationView* new_view =
           NotificationView::Create(this,
                                    *(*iter),
-                                   expanded,
                                    false); // Not creating a top-level
                                            // notification.
-      view->set_context_menu_controller(context_menu_controller_.get());
-      view->set_scroller(scroller_);
-      message_list_view_->UpdateNotificationAt(view, index);
-      notification_views_[id] = view;
+      new_view->set_context_menu_controller(context_menu_controller_.get());
+      new_view->set_scroller(scroller_);
+      message_list_view_->UpdateNotification(view, new_view);
+      notification_views_[id] = new_view;
       NotificationsChanged();
       break;
     }
@@ -984,10 +925,6 @@ void MessageCenterView::ClickOnNotificationButton(
   message_center_->ClickOnNotificationButton(notification_id, button_index);
 }
 
-void MessageCenterView::ExpandNotification(const std::string& notification_id) {
-  message_center_->ExpandNotification(notification_id);
-}
-
 void MessageCenterView::AnimationEnded(const gfx::Animation* animation) {
   DCHECK_EQ(animation, settings_transition_animation_.get());
 
@@ -1028,28 +965,14 @@ void MessageCenterView::AnimationCanceled(const gfx::Animation* animation) {
   AnimationEnded(animation);
 }
 
-
-void MessageCenterView::AddMessageViewAt(MessageView* view, int index) {
-  view->set_scroller(scroller_);
-  message_list_view_->AddNotificationAt(view, index);
-}
-
 void MessageCenterView::AddNotificationAt(const Notification& notification,
                                           int index) {
-  // NotificationViews are expanded by default here until
-  // http://crbug.com/217902 is fixed. TODO(dharcourt): Fix.
-  bool expanded = true;
-  if (IsExperimentalNotificationUIEnabled())
-    expanded = notification.is_expanded();
   NotificationView* view =
-      NotificationView::Create(this,
-                               notification,
-                               expanded,
-                               false);  // Not creating a top-level
-                                        // notification.
+      NotificationView::Create(this, notification, false);  // Not top-level.
   view->set_context_menu_controller(context_menu_controller_.get());
   notification_views_[notification.id()] = view;
-  AddMessageViewAt(view, index);
+  view->set_scroller(scroller_);
+  message_list_view_->AddNotificationAt(view, index);
 }
 
 void MessageCenterView::NotificationsChanged() {