Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ui / app_list / views / apps_container_view.cc
index 6a27555..d75fd78 100644 (file)
 
 #include <algorithm>
 
+#include "base/command_line.h"
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/app_list_folder_item.h"
+#include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/pagination_model.h"
 #include "ui/app_list/views/app_list_folder_view.h"
 #include "ui/app_list/views/app_list_item_view.h"
 #include "ui/app_list/views/app_list_main_view.h"
 #include "ui/app_list/views/apps_grid_view.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/app_list/views/folder_background_view.h"
 #include "ui/events/event.h"
-#include "ui/gfx/image/image_skia_operations.h"
-#include "ui/views/controls/image_view.h"
 
 namespace app_list {
 
-namespace {
-
-// Transitional view used for top item icons animation when opening or closing
-// a folder.
-class TopIconAnimationView : public views::View,
-                             public ui::ImplicitAnimationObserver {
- public:
-  TopIconAnimationView(const gfx::ImageSkia& icon,
-                       const gfx::Rect& scaled_rect,
-                       bool open_folder)
-      : icon_size_(kPreferredIconDimension, kPreferredIconDimension),
-        icon_(new views::ImageView),
-        scaled_rect_(scaled_rect),
-        open_folder_(open_folder) {
-    DCHECK(!icon.isNull());
-    gfx::ImageSkia resized(gfx::ImageSkiaOperations::CreateResizedImage(
-          icon,
-          skia::ImageOperations::RESIZE_BEST, icon_size_));
-    icon_->SetImage(resized);
-    AddChildView(icon_);
-
-#if defined(USE_AURA)
-    SetPaintToLayer(true);
-    SetFillsBoundsOpaquely(false);
-#endif
-  }
-  virtual ~TopIconAnimationView() {}
-
-  void AddObserver(TopIconAnimationObserver* observer) {
-    observers_.AddObserver(observer);
-  }
-
-  void RemoveObserver(TopIconAnimationObserver* observer) {
-    observers_.RemoveObserver(observer);
-  }
-
-  void TransformView() {
-    // Transform used for scaling down the icon and move it back inside to the
-    // original folder icon.
-    const float kIconTransformScale = 0.33333f;
-    gfx::Transform transform;
-    transform.Translate(scaled_rect_.x() - layer()->bounds().x(),
-                        scaled_rect_.y() - layer()->bounds().y());
-    transform.Scale(kIconTransformScale, kIconTransformScale);
-
-    if (open_folder_) {
-      // Transform to a scaled down icon inside the original folder icon.
-      layer()->SetTransform(transform);
-    }
-
-    // Animate the icon to its target location and scale when opening or
-    // closing a folder.
-    ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator());
-    settings.AddObserver(this);
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kFolderTransitionInDurationMs));
-    layer()->SetTransform(open_folder_ ? gfx::Transform() : transform);
-  }
-
- private:
-  // views::View overrides:
-  virtual gfx::Size GetPreferredSize() OVERRIDE {
-    return icon_size_;
-  }
-
-  virtual void Layout() OVERRIDE {
-    icon_->SetBoundsRect(GetContentsBounds());
-  }
-
-  // ui::ImplicitAnimationObserver overrides:
-  virtual void OnImplicitAnimationsCompleted() OVERRIDE {
-    SetVisible(false);
-    FOR_EACH_OBSERVER(TopIconAnimationObserver,
-                      observers_,
-                      OnTopIconAnimationsComplete(this));
-  }
-
-  gfx::Size icon_size_;
-  views::ImageView* icon_;  // Owned by views hierarchy.
-  // Rect of the scaled down top item icon inside folder icon's ink bubble.
-  gfx::Rect scaled_rect_;
-  // True: opening folder; False: closing folder.
-  bool open_folder_;
-
-  ObserverList<TopIconAnimationObserver> observers_;
-
-  DISALLOW_COPY_AND_ASSIGN(TopIconAnimationView);
-};
-
-}  // namespace
-
 AppsContainerView::AppsContainerView(AppListMainView* app_list_main_view,
                                      PaginationModel* pagination_model,
                                      AppListModel* model,
                                      content::WebContents* start_page_contents)
     : model_(model),
-      show_state_(SHOW_APPS) {
+      show_state_(SHOW_APPS),
+      top_icon_animation_pending_count_(0) {
   apps_grid_view_ = new AppsGridView(
       app_list_main_view, pagination_model, start_page_contents);
-  apps_grid_view_->SetLayout(kPreferredIconDimension,
-                             kPreferredCols,
-                             kPreferredRows);
+  int cols = kPreferredCols;
+  int rows = kPreferredRows;
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+      app_list::switches::kEnableExperimentalAppList)) {
+    cols = kExperimentalPreferredCols;
+    rows = kExperimentalPreferredRows;
+  }
+  apps_grid_view_->SetLayout(kPreferredIconDimension, cols, rows);
   AddChildView(apps_grid_view_);
 
+  folder_background_view_ = new FolderBackgroundView();
+  AddChildView(folder_background_view_);
+
   app_list_folder_view_ = new AppListFolderView(
       this,
       model,
@@ -133,6 +51,8 @@ AppsContainerView::AppsContainerView(AppListMainView* app_list_main_view,
 
   apps_grid_view_->SetModel(model_);
   apps_grid_view_->SetItemList(model_->item_list());
+  SetShowState(SHOW_APPS,
+               false);  /* show apps without animation */
 }
 
 AppsContainerView::~AppsContainerView() {
@@ -140,16 +60,28 @@ AppsContainerView::~AppsContainerView() {
 
 void AppsContainerView::ShowActiveFolder(AppListFolderItem* folder_item) {
   app_list_folder_view_->SetAppListFolderItem(folder_item);
-  SetShowState(SHOW_ACTIVE_FOLDER);
+  SetShowState(SHOW_ACTIVE_FOLDER, false);
 
   CreateViewsForFolderTopItemsAnimation(folder_item, true);
 }
 
 void AppsContainerView::ShowApps(AppListFolderItem* folder_item) {
-  CreateViewsForFolderTopItemsAnimation(folder_item, false);
-  // Hide the active folder view until the animation completes.
-  apps_grid_view_->activated_item_view()->SetVisible(false);
-  SetShowState(SHOW_APPS);
+  PrepareToShowApps(folder_item);
+  SetShowState(SHOW_APPS,
+               true);  /* show apps with animation */
+}
+
+void AppsContainerView::SetDragAndDropHostOfCurrentAppList(
+    ApplicationDragAndDropHost* drag_and_drop_host) {
+  apps_grid_view()->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
+  app_list_folder_view()->items_grid_view()->
+      SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
+}
+
+void AppsContainerView::ReparentFolderItemTransit(
+    AppListFolderItem* folder_item) {
+  PrepareToShowApps(folder_item);
+  SetShowState(SHOW_ITEM_REPARENT, false);
 }
 
 gfx::Size AppsContainerView::GetPreferredSize() {
@@ -168,14 +100,13 @@ void AppsContainerView::Layout() {
 
   switch (show_state_) {
     case SHOW_APPS:
-      app_list_folder_view_->ScheduleShowHideAnimation(false);
       apps_grid_view_->SetBoundsRect(rect);
-      apps_grid_view_->ScheduleShowHideAnimation(true);
       break;
     case SHOW_ACTIVE_FOLDER:
-      apps_grid_view_->ScheduleShowHideAnimation(false);
+      folder_background_view_->SetBoundsRect(rect);
       app_list_folder_view_->SetBoundsRect(rect);
-      app_list_folder_view_->ScheduleShowHideAnimation(true);
+      break;
+    case SHOW_ITEM_REPARENT:
       break;
     default:
       NOTREACHED();
@@ -189,44 +120,63 @@ bool AppsContainerView::OnKeyPressed(const ui::KeyEvent& event) {
     return app_list_folder_view_->OnKeyPressed(event);
 }
 
-void AppsContainerView::OnTopIconAnimationsComplete(views::View* icon_view) {
-  bool animations_done = true;
-  for (size_t i = 0; i < top_icon_views_.size(); ++i) {
-    if (top_icon_views_[i]->visible()) {
-      animations_done = false;
-      break;
-    }
-  }
+void AppsContainerView::OnTopIconAnimationsComplete() {
+  --top_icon_animation_pending_count_;
 
-  if (animations_done) {
-    // Clean up the transitional views using for top item icon animation.
-    for (size_t i = 0; i < top_icon_views_.size(); ++i) {
-      TopIconAnimationView* icon_view =
-          static_cast<TopIconAnimationView*>(top_icon_views_[i]);
-      icon_view->RemoveObserver(this);
-      delete icon_view;
-    }
+  if (!top_icon_animation_pending_count_) {
+    // Clean up the transitional views used for top item icon animation.
     top_icon_views_.clear();
 
     // Show the folder icon when closing the folder.
-    if (show_state_ == SHOW_APPS && apps_grid_view_->activated_item_view())
+    if ((show_state_ == SHOW_APPS || show_state_ == SHOW_ITEM_REPARENT) &&
+        apps_grid_view_->activated_item_view()) {
       apps_grid_view_->activated_item_view()->SetVisible(true);
+    }
   }
 }
 
-void AppsContainerView::SetShowState(ShowState show_state) {
+void AppsContainerView::SetShowState(ShowState show_state,
+                                     bool show_apps_with_animation) {
   if (show_state_ == show_state)
     return;
 
   show_state_ = show_state;
+
+  switch (show_state_) {
+    case SHOW_APPS:
+      folder_background_view_->SetVisible(false);
+      if (show_apps_with_animation) {
+        app_list_folder_view_->ScheduleShowHideAnimation(false, false);
+        apps_grid_view_->ScheduleShowHideAnimation(true);
+      } else {
+        app_list_folder_view_->HideViewImmediately();
+        apps_grid_view_->SetVisible(true);
+      }
+      break;
+    case SHOW_ACTIVE_FOLDER:
+      folder_background_view_->SetVisible(true);
+      apps_grid_view_->ScheduleShowHideAnimation(false);
+      app_list_folder_view_->ScheduleShowHideAnimation(true, false);
+      break;
+    case SHOW_ITEM_REPARENT:
+      folder_background_view_->SetVisible(false);
+      folder_background_view_->UpdateFolderContainerBubble(
+          FolderBackgroundView::NO_BUBBLE);
+      app_list_folder_view_->ScheduleShowHideAnimation(false, true);
+      apps_grid_view_->ScheduleShowHideAnimation(true);
+      break;
+    default:
+      NOTREACHED();
+  }
+
   Layout();
 }
 
 Rects AppsContainerView::GetTopItemIconBoundsInActiveFolder() {
   // Get the active folder's icon bounds relative to AppsContainerView.
-  AppListItemView* folder_view = apps_grid_view_->activated_item_view();
-  gfx::Rect to_grid_view = folder_view->ConvertRectToParent(
-      folder_view->GetIconBounds());
+  AppListItemView* folder_item_view = apps_grid_view_->activated_item_view();
+  gfx::Rect to_grid_view = folder_item_view->ConvertRectToParent(
+      folder_item_view->GetIconBounds());
   gfx::Rect to_container = apps_grid_view_->ConvertRectToParent(to_grid_view);
 
   return AppListFolderItem::GetTopIconsBounds(to_container);
@@ -238,9 +188,9 @@ void AppsContainerView::CreateViewsForFolderTopItemsAnimation(
   top_icon_views_.clear();
   std::vector<gfx::Rect> top_items_bounds =
       GetTopItemIconBoundsInActiveFolder();
-  size_t top_items_count =
+  top_icon_animation_pending_count_ =
       std::min(kNumFolderTopItems, active_folder->item_list()->item_count());
-  for (size_t i = 0; i < top_items_count; ++i) {
+  for (size_t i = 0; i < top_icon_animation_pending_count_; ++i) {
     TopIconAnimationView* icon_view = new TopIconAnimationView(
         active_folder->GetTopIcon(i), top_items_bounds[i], open_folder);
     icon_view->AddObserver(this);
@@ -256,4 +206,13 @@ void AppsContainerView::CreateViewsForFolderTopItemsAnimation(
   }
 }
 
+void AppsContainerView::PrepareToShowApps(AppListFolderItem* folder_item) {
+  if (folder_item)
+    CreateViewsForFolderTopItemsAnimation(folder_item, false);
+
+  // Hide the active folder item until the animation completes.
+  if (apps_grid_view_->activated_item_view())
+    apps_grid_view_->activated_item_view()->SetVisible(false);
+}
+
 }  // namespace app_list