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