Task Manager: Remove goat teleporter.
[chromium-blink-merge.git] / ui / app_list / views / contents_view.cc
blob3b4d620ffa723bc8276b18be45bbd5db75a73585
1 // Copyright (c) 2012 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/contents_view.h"
7 #include <algorithm>
8 #include <vector>
10 #include "base/logging.h"
11 #include "ui/app_list/app_list_constants.h"
12 #include "ui/app_list/app_list_switches.h"
13 #include "ui/app_list/app_list_view_delegate.h"
14 #include "ui/app_list/views/app_list_folder_view.h"
15 #include "ui/app_list/views/app_list_main_view.h"
16 #include "ui/app_list/views/apps_container_view.h"
17 #include "ui/app_list/views/apps_grid_view.h"
18 #include "ui/app_list/views/contents_switcher_view.h"
19 #include "ui/app_list/views/search_result_list_view.h"
20 #include "ui/app_list/views/start_page_view.h"
21 #include "ui/events/event.h"
22 #include "ui/resources/grit/ui_resources.h"
23 #include "ui/views/view_model.h"
24 #include "ui/views/view_model_utils.h"
26 namespace app_list {
28 ContentsView::ContentsView(AppListMainView* app_list_main_view)
29 : search_results_view_(NULL),
30 start_page_view_(NULL),
31 app_list_main_view_(app_list_main_view),
32 contents_switcher_view_(NULL),
33 view_model_(new views::ViewModel),
34 page_before_search_(0) {
35 pagination_model_.AddObserver(this);
38 ContentsView::~ContentsView() {
39 pagination_model_.RemoveObserver(this);
40 if (contents_switcher_view_)
41 pagination_model_.RemoveObserver(contents_switcher_view_);
44 void ContentsView::InitNamedPages(AppListModel* model,
45 AppListViewDelegate* view_delegate) {
46 DCHECK(model);
48 if (app_list::switches::IsExperimentalAppListEnabled()) {
49 start_page_view_ = new StartPageView(app_list_main_view_, view_delegate);
50 AddLauncherPage(start_page_view_, 0, NAMED_PAGE_START);
51 } else {
52 search_results_view_ =
53 new SearchResultListView(app_list_main_view_, view_delegate);
54 AddLauncherPage(search_results_view_, 0, NAMED_PAGE_SEARCH_RESULTS);
55 search_results_view_->SetResults(model->results());
58 apps_container_view_ = new AppsContainerView(app_list_main_view_, model);
60 AddLauncherPage(
61 apps_container_view_, IDR_APP_LIST_APPS_ICON, NAMED_PAGE_APPS);
63 if (app_list::switches::IsExperimentalAppListEnabled()) {
64 std::vector<views::View*> custom_page_views =
65 view_delegate->CreateCustomPageWebViews(GetLocalBounds().size());
66 for (std::vector<views::View*>::const_iterator it =
67 custom_page_views.begin();
68 it != custom_page_views.end();
69 ++it) {
70 AddLauncherPage(*it, IDR_APP_LIST_NOTIFICATIONS_ICON);
74 int initial_page_index = app_list::switches::IsExperimentalAppListEnabled()
75 ? GetPageIndexForNamedPage(NAMED_PAGE_START)
76 : GetPageIndexForNamedPage(NAMED_PAGE_APPS);
78 page_before_search_ = initial_page_index;
79 pagination_model_.SelectPage(initial_page_index, false);
81 // Needed to update the main search box visibility.
82 ActivePageChanged(false);
85 void ContentsView::CancelDrag() {
86 if (apps_container_view_->apps_grid_view()->has_dragged_view())
87 apps_container_view_->apps_grid_view()->EndDrag(true);
88 if (apps_container_view_->app_list_folder_view()
89 ->items_grid_view()
90 ->has_dragged_view()) {
91 apps_container_view_->app_list_folder_view()->items_grid_view()->EndDrag(
92 true);
96 void ContentsView::SetDragAndDropHostOfCurrentAppList(
97 ApplicationDragAndDropHost* drag_and_drop_host) {
98 apps_container_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
101 void ContentsView::SetContentsSwitcherView(
102 ContentsSwitcherView* contents_switcher_view) {
103 DCHECK(!contents_switcher_view_);
104 contents_switcher_view_ = contents_switcher_view;
105 if (contents_switcher_view_)
106 pagination_model_.AddObserver(contents_switcher_view_);
109 void ContentsView::SetActivePage(int page_index) {
110 if (GetActivePageIndex() == page_index)
111 return;
113 SetActivePageInternal(page_index, false);
116 int ContentsView::GetActivePageIndex() const {
117 // The active page is changed at the beginning of an animation, not the end.
118 return pagination_model_.SelectedTargetPage();
121 bool ContentsView::IsNamedPageActive(NamedPage named_page) const {
122 std::map<NamedPage, int>::const_iterator it =
123 named_page_to_view_.find(named_page);
124 if (it == named_page_to_view_.end())
125 return false;
126 return it->second == GetActivePageIndex();
129 int ContentsView::GetPageIndexForNamedPage(NamedPage named_page) const {
130 // Find the index of the view corresponding to the given named_page.
131 std::map<NamedPage, int>::const_iterator it =
132 named_page_to_view_.find(named_page);
133 // GetPageIndexForNamedPage should never be called on a named_page that does
134 // not have a corresponding view.
135 DCHECK(it != named_page_to_view_.end());
136 return it->second;
139 int ContentsView::NumLauncherPages() const {
140 return pagination_model_.total_pages();
143 void ContentsView::SetActivePageInternal(int page_index,
144 bool show_search_results) {
145 if (!show_search_results)
146 page_before_search_ = page_index;
147 // Start animating to the new page.
148 pagination_model_.SelectPage(page_index, true);
149 ActivePageChanged(show_search_results);
152 void ContentsView::ActivePageChanged(bool show_search_results) {
153 // TODO(xiyuan): Highlight default match instead of the first.
154 if (IsNamedPageActive(NAMED_PAGE_SEARCH_RESULTS) &&
155 search_results_view_->visible()) {
156 search_results_view_->SetSelectedIndex(0);
158 if (search_results_view_)
159 search_results_view_->UpdateAutoLaunchState();
161 if (IsNamedPageActive(NAMED_PAGE_START)) {
162 if (show_search_results)
163 start_page_view_->ShowSearchResults();
164 else
165 start_page_view_->Reset();
168 // Notify parent AppListMainView of the page change.
169 app_list_main_view_->UpdateSearchBoxVisibility();
172 void ContentsView::ShowSearchResults(bool show) {
173 int search_page = GetPageIndexForNamedPage(
174 app_list::switches::IsExperimentalAppListEnabled()
175 ? NAMED_PAGE_START
176 : NAMED_PAGE_SEARCH_RESULTS);
178 SetActivePageInternal(show ? search_page : page_before_search_, show);
181 bool ContentsView::IsShowingSearchResults() const {
182 return app_list::switches::IsExperimentalAppListEnabled()
183 ? IsNamedPageActive(NAMED_PAGE_START) &&
184 start_page_view_->IsShowingSearchResults()
185 : IsNamedPageActive(NAMED_PAGE_SEARCH_RESULTS);
188 void ContentsView::UpdatePageBounds() {
189 gfx::Rect rect(GetContentsBounds());
190 if (rect.IsEmpty())
191 return;
193 // The bounds calculations will potentially be mid-transition (depending on
194 // the state of the PaginationModel).
195 int current_page = std::max(0, pagination_model_.selected_page());
196 int target_page = current_page;
197 double progress = 1;
198 if (pagination_model_.has_transition()) {
199 const PaginationModel::Transition& transition =
200 pagination_model_.transition();
201 if (pagination_model_.is_valid_page(transition.target_page)) {
202 target_page = transition.target_page;
203 progress = transition.progress;
207 gfx::Rect incoming_target(rect);
208 gfx::Rect outgoing_target(rect);
209 int dir = target_page > current_page ? -1 : 1;
211 // Pages transition vertically.
212 int page_height = rect.height();
213 int transition_offset = progress * page_height * dir;
215 outgoing_target.set_y(transition_offset);
216 incoming_target.set_y(dir < 0 ? transition_offset + page_height
217 : transition_offset - page_height);
219 view_model_->view_at(current_page)->SetBoundsRect(outgoing_target);
220 view_model_->view_at(target_page)->SetBoundsRect(incoming_target);
223 PaginationModel* ContentsView::GetAppsPaginationModel() {
224 return apps_container_view_->apps_grid_view()->pagination_model();
227 void ContentsView::ShowFolderContent(AppListFolderItem* item) {
228 apps_container_view_->ShowActiveFolder(item);
231 void ContentsView::Prerender() {
232 apps_container_view_->apps_grid_view()->Prerender();
235 views::View* ContentsView::GetPageView(int index) {
236 return view_model_->view_at(index);
239 void ContentsView::AddBlankPageForTesting() {
240 AddLauncherPage(new views::View, 0);
243 int ContentsView::AddLauncherPage(views::View* view, int resource_id) {
244 int page_index = view_model_->view_size();
245 AddChildView(view);
246 view_model_->Add(view, page_index);
247 if (contents_switcher_view_ && resource_id)
248 contents_switcher_view_->AddSwitcherButton(resource_id, page_index);
249 pagination_model_.SetTotalPages(view_model_->view_size());
250 return page_index;
253 int ContentsView::AddLauncherPage(views::View* view,
254 int resource_id,
255 NamedPage named_page) {
256 int page_index = AddLauncherPage(view, resource_id);
257 named_page_to_view_.insert(std::pair<NamedPage, int>(named_page, page_index));
258 return page_index;
261 gfx::Size ContentsView::GetPreferredSize() const {
262 const gfx::Size container_size =
263 apps_container_view_->apps_grid_view()->GetPreferredSize();
264 const gfx::Size results_size = search_results_view_
265 ? search_results_view_->GetPreferredSize()
266 : gfx::Size();
268 int width = std::max(container_size.width(), results_size.width());
269 int height = std::max(container_size.height(), results_size.height());
270 return gfx::Size(width, height);
273 void ContentsView::Layout() {
274 // Immediately finish all current animations.
275 pagination_model_.FinishAnimation();
277 // Move the current view onto the screen, and all other views off screen to
278 // the left. (Since we are not animating, we don't need to be careful about
279 // which side we place the off-screen views onto.)
280 gfx::Rect rect(GetContentsBounds());
281 if (rect.IsEmpty())
282 return;
284 gfx::Rect offscreen_target(rect);
285 offscreen_target.set_x(-rect.width());
287 for (int i = 0; i < view_model_->view_size(); ++i) {
288 view_model_->view_at(i)->SetBoundsRect(
289 i == pagination_model_.SelectedTargetPage() ? rect : offscreen_target);
293 bool ContentsView::OnKeyPressed(const ui::KeyEvent& event) {
294 return view_model_->view_at(GetActivePageIndex())->OnKeyPressed(event);
297 void ContentsView::TotalPagesChanged() {
300 void ContentsView::SelectedPageChanged(int old_selected, int new_selected) {
303 void ContentsView::TransitionStarted() {
306 void ContentsView::TransitionChanged() {
307 UpdatePageBounds();
310 } // namespace app_list