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"
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"
23 AppsContainerView::AppsContainerView(AppListMainView
* app_list_main_view
,
26 show_state_(SHOW_NONE
),
27 top_icon_animation_pending_count_(0) {
28 apps_grid_view_
= new AppsGridView(app_list_main_view
);
31 if (switches::IsExperimentalAppListEnabled()) {
32 cols
= kExperimentalPreferredCols
;
33 rows
= kExperimentalPreferredRows
;
34 } else if (app_list_main_view
->ShouldCenterWindow()) {
35 cols
= kCenteredPreferredCols
;
36 rows
= kCenteredPreferredRows
;
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_
)
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_
)
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_
)
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());
128 switch (show_state_
) {
130 apps_grid_view_
->SetBoundsRect(rect
);
132 case SHOW_ACTIVE_FOLDER
:
133 folder_background_view_
->SetBoundsRect(rect
);
134 app_list_folder_view_
->SetBoundsRect(rect
);
136 case SHOW_ITEM_REPARENT
:
143 bool AppsContainerView::OnKeyPressed(const ui::KeyEvent
& event
) {
144 if (show_state_
== SHOW_APPS
)
145 return apps_grid_view_
->OnKeyPressed(event
);
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
)
184 show_state_
= show_state
;
186 switch (show_state_
) {
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);
193 app_list_folder_view_
->HideViewImmediately();
194 apps_grid_view_
->ResetForShowApps();
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);
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);
213 app_list_folder_view_
->SetBackButtonLabel(IsInFolderView());
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
,
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())
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
) {
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