Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / ui / app_list / views / apps_container_view.cc
blobc47d3b7478dfc0a7cb42339e8858e1fd4dcf6a7b
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.
5 #include "ui/app_list/views/apps_container_view.h"
7 #include <algorithm>
8 #include <vector>
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"
21 namespace app_list {
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;
41 apps_grid_view_->SetLayout(cols, rows);
42 AddChildView(apps_grid_view_);
44 folder_background_view_ = new FolderBackgroundView();
45 AddChildView(folder_background_view_);
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_);
53 apps_grid_view_->SetModel(model_);
54 apps_grid_view_->SetItemList(model_->top_level_item_list());
55 SetShowState(SHOW_APPS, false);
58 AppsContainerView::~AppsContainerView() {
61 void AppsContainerView::ShowActiveFolder(AppListFolderItem* folder_item) {
62 // Prevent new animations from starting if there are currently animations
63 // pending. This fixes crbug.com/357099.
64 if (top_icon_animation_pending_count_)
65 return;
67 app_list_folder_view_->SetAppListFolderItem(folder_item);
68 SetShowState(SHOW_ACTIVE_FOLDER, false);
70 CreateViewsForFolderTopItemsAnimation(folder_item, true);
72 apps_grid_view_->ClearAnySelectedView();
75 void AppsContainerView::ShowApps(AppListFolderItem* folder_item) {
76 if (top_icon_animation_pending_count_)
77 return;
79 PrepareToShowApps(folder_item);
80 SetShowState(SHOW_APPS, true);
83 void AppsContainerView::ResetForShowApps() {
84 SetShowState(SHOW_APPS, false);
85 folder_background_view_->UpdateFolderContainerBubble(
86 FolderBackgroundView::NO_BUBBLE);
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);
96 void AppsContainerView::ReparentFolderItemTransit(
97 AppListFolderItem* folder_item) {
98 if (top_icon_animation_pending_count_)
99 return;
101 PrepareToShowApps(folder_item);
102 SetShowState(SHOW_ITEM_REPARENT, false);
105 bool AppsContainerView::IsInFolderView() const {
106 return show_state_ == SHOW_ACTIVE_FOLDER;
109 void AppsContainerView::ReparentDragEnded() {
110 DCHECK_EQ(SHOW_ITEM_REPARENT, show_state_);
111 show_state_ = AppsContainerView::SHOW_APPS;
114 gfx::Size AppsContainerView::GetPreferredSize() const {
115 const gfx::Size grid_size = apps_grid_view_->GetPreferredSize();
116 const gfx::Size folder_view_size = app_list_folder_view_->GetPreferredSize();
118 int width = std::max(grid_size.width(), folder_view_size.width());
119 int height = std::max(grid_size.height(), folder_view_size.height());
120 return gfx::Size(width, height);
123 void AppsContainerView::Layout() {
124 gfx::Rect rect(GetContentsBounds());
125 if (rect.IsEmpty())
126 return;
128 switch (show_state_) {
129 case SHOW_APPS:
130 apps_grid_view_->SetBoundsRect(rect);
131 break;
132 case SHOW_ACTIVE_FOLDER:
133 folder_background_view_->SetBoundsRect(rect);
134 app_list_folder_view_->SetBoundsRect(rect);
135 break;
136 case SHOW_ITEM_REPARENT:
137 break;
138 default:
139 NOTREACHED();
143 bool AppsContainerView::OnKeyPressed(const ui::KeyEvent& event) {
144 if (show_state_ == SHOW_APPS)
145 return apps_grid_view_->OnKeyPressed(event);
146 else
147 return app_list_folder_view_->OnKeyPressed(event);
150 void AppsContainerView::OnWillBeShown() {
151 apps_grid_view()->ClearAnySelectedView();
152 app_list_folder_view()->items_grid_view()->ClearAnySelectedView();
155 gfx::Rect AppsContainerView::GetPageBoundsForState(
156 AppListModel::State state) const {
157 gfx::Rect onscreen_bounds = GetDefaultContentsBounds();
158 if (state == AppListModel::STATE_APPS)
159 return onscreen_bounds;
161 return GetBelowContentsOffscreenBounds(onscreen_bounds.size());
164 void AppsContainerView::OnTopIconAnimationsComplete() {
165 --top_icon_animation_pending_count_;
167 if (!top_icon_animation_pending_count_) {
168 // Clean up the transitional views used for top item icon animation.
169 top_icon_views_.clear();
171 // Show the folder icon when closing the folder.
172 if ((show_state_ == SHOW_APPS || show_state_ == SHOW_ITEM_REPARENT) &&
173 apps_grid_view_->activated_folder_item_view()) {
174 apps_grid_view_->activated_folder_item_view()->SetVisible(true);
179 void AppsContainerView::SetShowState(ShowState show_state,
180 bool show_apps_with_animation) {
181 if (show_state_ == show_state)
182 return;
184 show_state_ = show_state;
186 switch (show_state_) {
187 case SHOW_APPS:
188 folder_background_view_->SetVisible(false);
189 if (show_apps_with_animation) {
190 app_list_folder_view_->ScheduleShowHideAnimation(false, false);
191 apps_grid_view_->ScheduleShowHideAnimation(true);
192 } else {
193 app_list_folder_view_->HideViewImmediately();
194 apps_grid_view_->ResetForShowApps();
196 break;
197 case SHOW_ACTIVE_FOLDER:
198 folder_background_view_->SetVisible(true);
199 apps_grid_view_->ScheduleShowHideAnimation(false);
200 app_list_folder_view_->ScheduleShowHideAnimation(true, false);
201 break;
202 case SHOW_ITEM_REPARENT:
203 folder_background_view_->SetVisible(false);
204 folder_background_view_->UpdateFolderContainerBubble(
205 FolderBackgroundView::NO_BUBBLE);
206 app_list_folder_view_->ScheduleShowHideAnimation(false, true);
207 apps_grid_view_->ScheduleShowHideAnimation(true);
208 break;
209 default:
210 NOTREACHED();
213 app_list_folder_view_->SetBackButtonLabel(IsInFolderView());
214 Layout();
217 std::vector<gfx::Rect> AppsContainerView::GetTopItemIconBoundsInActiveFolder() {
218 // Get the active folder's icon bounds relative to AppsContainerView.
219 AppListItemView* folder_item_view =
220 apps_grid_view_->activated_folder_item_view();
221 gfx::Rect to_grid_view = folder_item_view->ConvertRectToParent(
222 folder_item_view->GetIconBounds());
223 gfx::Rect to_container = apps_grid_view_->ConvertRectToParent(to_grid_view);
225 return FolderImage::GetTopIconsBounds(to_container);
228 void AppsContainerView::CreateViewsForFolderTopItemsAnimation(
229 AppListFolderItem* active_folder,
230 bool open_folder) {
231 top_icon_views_.clear();
232 std::vector<gfx::Rect> top_items_bounds =
233 GetTopItemIconBoundsInActiveFolder();
234 top_icon_animation_pending_count_ =
235 std::min(kNumFolderTopItems, active_folder->item_list()->item_count());
236 for (size_t i = 0; i < top_icon_animation_pending_count_; ++i) {
237 if (active_folder->GetTopIcon(i).isNull())
238 continue;
240 TopIconAnimationView* icon_view = new TopIconAnimationView(
241 active_folder->GetTopIcon(i), top_items_bounds[i], open_folder);
242 icon_view->AddObserver(this);
243 top_icon_views_.push_back(icon_view);
245 // Add the transitional views into child views, and set its bounds to the
246 // same location of the item in the folder list view.
247 AddChildView(top_icon_views_[i]);
248 top_icon_views_[i]->SetBoundsRect(
249 app_list_folder_view_->ConvertRectToParent(
250 app_list_folder_view_->GetItemIconBoundsAt(i)));
251 static_cast<TopIconAnimationView*>(top_icon_views_[i])->TransformView();
255 void AppsContainerView::PrepareToShowApps(AppListFolderItem* folder_item) {
256 if (folder_item)
257 CreateViewsForFolderTopItemsAnimation(folder_item, false);
259 // Hide the active folder item until the animation completes.
260 if (apps_grid_view_->activated_folder_item_view())
261 apps_grid_view_->activated_folder_item_view()->SetVisible(false);
264 } // namespace app_list