Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / ui / app_list / views / apps_container_view.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/app_list/views/apps_container_view.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/command_line.h"
11 #include "ui/app_list/app_list_constants.h"
12 #include "ui/app_list/app_list_folder_item.h"
13 #include "ui/app_list/app_list_switches.h"
14 #include "ui/app_list/views/app_list_folder_view.h"
15 #include "ui/app_list/views/app_list_item_view.h"
16 #include "ui/app_list/views/app_list_main_view.h"
17 #include "ui/app_list/views/apps_grid_view.h"
18 #include "ui/app_list/views/folder_background_view.h"
19 #include "ui/events/event.h"
20
21 namespace app_list {
22
23 AppsContainerView::AppsContainerView(AppListMainView* app_list_main_view,
24                                      AppListModel* model)
25     : model_(model),
26       show_state_(SHOW_NONE),
27       top_icon_animation_pending_count_(0) {
28   apps_grid_view_ = new AppsGridView(app_list_main_view);
29   int cols;
30   int rows;
31   if (switches::IsExperimentalAppListEnabled()) {
32     cols = kExperimentalPreferredCols;
33     rows = kExperimentalPreferredRows;
34   } else if (app_list_main_view->ShouldCenterWindow()) {
35     cols = kCenteredPreferredCols;
36     rows = kCenteredPreferredRows;
37   } else {
38     cols = kPreferredCols;
39     rows = kPreferredRows;
40   }
41   apps_grid_view_->SetLayout(cols, rows);
42   AddChildView(apps_grid_view_);
43
44   folder_background_view_ = new FolderBackgroundView();
45   AddChildView(folder_background_view_);
46
47   app_list_folder_view_ =
48       new AppListFolderView(this, model, app_list_main_view);
49   // The folder view is initially hidden.
50   app_list_folder_view_->SetVisible(false);
51   AddChildView(app_list_folder_view_);
52
53   apps_grid_view_->SetModel(model_);
54   apps_grid_view_->SetItemList(model_->top_level_item_list());
55   SetShowState(SHOW_APPS,
56                false);  /* show apps without animation */
57 }
58
59 AppsContainerView::~AppsContainerView() {
60 }
61
62 void AppsContainerView::ShowActiveFolder(AppListFolderItem* folder_item) {
63   // Prevent new animations from starting if there are currently animations
64   // pending. This fixes crbug.com/357099.
65   if (top_icon_animation_pending_count_)
66     return;
67
68   app_list_folder_view_->SetAppListFolderItem(folder_item);
69   SetShowState(SHOW_ACTIVE_FOLDER, false);
70
71   CreateViewsForFolderTopItemsAnimation(folder_item, true);
72 }
73
74 void AppsContainerView::ShowApps(AppListFolderItem* folder_item) {
75   if (top_icon_animation_pending_count_)
76     return;
77
78   PrepareToShowApps(folder_item);
79   SetShowState(SHOW_APPS,
80                true);  /* show apps with animation */
81 }
82
83 void AppsContainerView::ResetForShowApps() {
84   SetShowState(SHOW_APPS, false /* show apps without animation */);
85   folder_background_view_->UpdateFolderContainerBubble(
86       FolderBackgroundView::NO_BUBBLE);
87 }
88
89 void AppsContainerView::SetDragAndDropHostOfCurrentAppList(
90     ApplicationDragAndDropHost* drag_and_drop_host) {
91   apps_grid_view()->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
92   app_list_folder_view()->items_grid_view()->
93       SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
94 }
95
96 void AppsContainerView::ReparentFolderItemTransit(
97     AppListFolderItem* folder_item) {
98   if (top_icon_animation_pending_count_)
99     return;
100
101   PrepareToShowApps(folder_item);
102   SetShowState(SHOW_ITEM_REPARENT, false);
103 }
104
105 bool AppsContainerView::IsInFolderView() const {
106   return show_state_ == SHOW_ACTIVE_FOLDER;
107 }
108
109 gfx::Size AppsContainerView::GetPreferredSize() const {
110   const gfx::Size grid_size = apps_grid_view_->GetPreferredSize();
111   const gfx::Size folder_view_size = app_list_folder_view_->GetPreferredSize();
112
113   int width = std::max(grid_size.width(), folder_view_size.width());
114   int height = std::max(grid_size.height(), folder_view_size.height());
115   return gfx::Size(width, height);
116 }
117
118 void AppsContainerView::Layout() {
119   gfx::Rect rect(GetContentsBounds());
120   if (rect.IsEmpty())
121     return;
122
123   switch (show_state_) {
124     case SHOW_APPS:
125       apps_grid_view_->SetBoundsRect(rect);
126       break;
127     case SHOW_ACTIVE_FOLDER:
128       folder_background_view_->SetBoundsRect(rect);
129       app_list_folder_view_->SetBoundsRect(rect);
130       break;
131     case SHOW_ITEM_REPARENT:
132       break;
133     default:
134       NOTREACHED();
135   }
136 }
137
138 bool AppsContainerView::OnKeyPressed(const ui::KeyEvent& event) {
139   if (show_state_ == SHOW_APPS)
140     return apps_grid_view_->OnKeyPressed(event);
141   else
142     return app_list_folder_view_->OnKeyPressed(event);
143 }
144
145 void AppsContainerView::OnTopIconAnimationsComplete() {
146   --top_icon_animation_pending_count_;
147
148   if (!top_icon_animation_pending_count_) {
149     // Clean up the transitional views used for top item icon animation.
150     top_icon_views_.clear();
151
152     // Show the folder icon when closing the folder.
153     if ((show_state_ == SHOW_APPS || show_state_ == SHOW_ITEM_REPARENT) &&
154         apps_grid_view_->activated_folder_item_view()) {
155       apps_grid_view_->activated_folder_item_view()->SetVisible(true);
156     }
157   }
158 }
159
160 void AppsContainerView::SetShowState(ShowState show_state,
161                                      bool show_apps_with_animation) {
162   if (show_state_ == show_state)
163     return;
164
165   show_state_ = show_state;
166
167   switch (show_state_) {
168     case SHOW_APPS:
169       folder_background_view_->SetVisible(false);
170       if (show_apps_with_animation) {
171         app_list_folder_view_->ScheduleShowHideAnimation(false, false);
172         apps_grid_view_->ScheduleShowHideAnimation(true);
173       } else {
174         app_list_folder_view_->HideViewImmediately();
175         apps_grid_view_->ResetForShowApps();
176       }
177       break;
178     case SHOW_ACTIVE_FOLDER:
179       folder_background_view_->SetVisible(true);
180       apps_grid_view_->ScheduleShowHideAnimation(false);
181       app_list_folder_view_->ScheduleShowHideAnimation(true, false);
182       break;
183     case SHOW_ITEM_REPARENT:
184       folder_background_view_->SetVisible(false);
185       folder_background_view_->UpdateFolderContainerBubble(
186           FolderBackgroundView::NO_BUBBLE);
187       app_list_folder_view_->ScheduleShowHideAnimation(false, true);
188       apps_grid_view_->ScheduleShowHideAnimation(true);
189       break;
190     default:
191       NOTREACHED();
192   }
193
194   Layout();
195 }
196
197 Rects AppsContainerView::GetTopItemIconBoundsInActiveFolder() {
198   // Get the active folder's icon bounds relative to AppsContainerView.
199   AppListItemView* folder_item_view =
200       apps_grid_view_->activated_folder_item_view();
201   gfx::Rect to_grid_view = folder_item_view->ConvertRectToParent(
202       folder_item_view->GetIconBounds());
203   gfx::Rect to_container = apps_grid_view_->ConvertRectToParent(to_grid_view);
204
205   return AppListFolderItem::GetTopIconsBounds(to_container);
206 }
207
208 void AppsContainerView::CreateViewsForFolderTopItemsAnimation(
209     AppListFolderItem* active_folder,
210     bool open_folder) {
211   top_icon_views_.clear();
212   std::vector<gfx::Rect> top_items_bounds =
213       GetTopItemIconBoundsInActiveFolder();
214   top_icon_animation_pending_count_ =
215       std::min(kNumFolderTopItems, active_folder->item_list()->item_count());
216   for (size_t i = 0; i < top_icon_animation_pending_count_; ++i) {
217     if (active_folder->GetTopIcon(i).isNull())
218       continue;
219
220     TopIconAnimationView* icon_view = new TopIconAnimationView(
221         active_folder->GetTopIcon(i), top_items_bounds[i], open_folder);
222     icon_view->AddObserver(this);
223     top_icon_views_.push_back(icon_view);
224
225     // Add the transitional views into child views, and set its bounds to the
226     // same location of the item in the folder list view.
227     AddChildView(top_icon_views_[i]);
228     top_icon_views_[i]->SetBoundsRect(
229         app_list_folder_view_->ConvertRectToParent(
230             app_list_folder_view_->GetItemIconBoundsAt(i)));
231     static_cast<TopIconAnimationView*>(top_icon_views_[i])->TransformView();
232   }
233 }
234
235 void AppsContainerView::PrepareToShowApps(AppListFolderItem* folder_item) {
236   if (folder_item)
237     CreateViewsForFolderTopItemsAnimation(folder_item, false);
238
239   // Hide the active folder item until the animation completes.
240   if (apps_grid_view_->activated_folder_item_view())
241     apps_grid_view_->activated_folder_item_view()->SetVisible(false);
242 }
243
244 }  // namespace app_list