Paint state transition for overlay 9 patch scrollbars
[chromium-blink-merge.git] / ui / app_list / views / apps_container_view.cc
blobdd30b8d5bea406521754d8e1375468c5b712e840
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 = 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;
36 apps_grid_view_->SetLayout(kPreferredIconDimension, cols, rows);
37 AddChildView(apps_grid_view_);
39 folder_background_view_ = new FolderBackgroundView();
40 AddChildView(folder_background_view_);
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_);
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 */
54 AppsContainerView::~AppsContainerView() {
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;
63 app_list_folder_view_->SetAppListFolderItem(folder_item);
64 SetShowState(SHOW_ACTIVE_FOLDER, false);
66 CreateViewsForFolderTopItemsAnimation(folder_item, true);
69 void AppsContainerView::ShowApps(AppListFolderItem* folder_item) {
70 if (top_icon_animation_pending_count_)
71 return;
73 PrepareToShowApps(folder_item);
74 SetShowState(SHOW_APPS,
75 true); /* show apps with animation */
78 void AppsContainerView::ResetForShowApps() {
79 SetShowState(SHOW_APPS, false /* show apps without animation */);
80 folder_background_view_->UpdateFolderContainerBubble(
81 FolderBackgroundView::NO_BUBBLE);
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);
91 void AppsContainerView::ReparentFolderItemTransit(
92 AppListFolderItem* folder_item) {
93 if (top_icon_animation_pending_count_)
94 return;
96 PrepareToShowApps(folder_item);
97 SetShowState(SHOW_ITEM_REPARENT, false);
100 bool AppsContainerView::IsInFolderView() const {
101 return show_state_ == SHOW_ACTIVE_FOLDER;
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();
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);
113 void AppsContainerView::Layout() {
114 gfx::Rect rect(GetContentsBounds());
115 if (rect.IsEmpty())
116 return;
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();
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);
140 void AppsContainerView::OnTopIconAnimationsComplete() {
141 --top_icon_animation_pending_count_;
143 if (!top_icon_animation_pending_count_) {
144 // Clean up the transitional views used for top item icon animation.
145 top_icon_views_.clear();
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);
155 void AppsContainerView::SetShowState(ShowState show_state,
156 bool show_apps_with_animation) {
157 if (show_state_ == show_state)
158 return;
160 show_state_ = show_state;
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();
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();
189 Layout();
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);
200 return AppListFolderItem::GetTopIconsBounds(to_container);
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;
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);
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();
230 void AppsContainerView::PrepareToShowApps(AppListFolderItem* folder_item) {
231 if (folder_item)
232 CreateViewsForFolderTopItemsAnimation(folder_item, false);
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);
239 } // namespace app_list