1 // Copyright 2014 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_animator.h"
7 #include "ui/app_list/app_list_constants.h"
8 #include "ui/app_list/app_list_switches.h"
9 #include "ui/app_list/views/app_list_main_view.h"
10 #include "ui/app_list/views/contents_view.h"
11 #include "ui/app_list/views/search_box_view.h"
12 #include "ui/app_list/views/start_page_view.h"
13 #include "ui/gfx/animation/tween.h"
14 #include "ui/gfx/geometry/rect.h"
15 #include "ui/views/view.h"
16 #include "ui/views/widget/widget.h"
22 ContentsAnimator::ContentsAnimator(ContentsView
* contents_view
)
23 : contents_view_(contents_view
) {
26 ContentsAnimator::~ContentsAnimator() {
29 gfx::Rect
ContentsAnimator::GetOnscreenPageBounds(int page_index
) const {
30 return contents_view_
->IsStateActive(AppListModel::STATE_CUSTOM_LAUNCHER_PAGE
)
31 ? contents_view_
->GetContentsBounds()
32 : contents_view_
->GetDefaultContentsBounds();
35 gfx::Rect
ContentsAnimator::GetOffscreenPageBounds(int page_index
) const {
36 gfx::Rect
bounds(contents_view_
->GetContentsBounds());
37 // The start page and search page origins are above; all other pages' origins
39 int page_height
= bounds
.height();
40 bool origin_above
= contents_view_
->GetPageIndexForState(
41 AppListModel::STATE_START
) == page_index
||
42 contents_view_
->GetPageIndexForState(
43 AppListModel::STATE_SEARCH_RESULTS
) == page_index
;
44 bounds
.set_y(origin_above
? -page_height
: page_height
);
48 void ContentsAnimator::UpdateCustomPageForDefaultAnimation(double progress
,
51 int custom_page_index
= contents_view()->GetPageIndexForState(
52 AppListModel::STATE_CUSTOM_LAUNCHER_PAGE
);
53 if (custom_page_index
< 0)
56 int start_page_index
=
57 contents_view()->GetPageIndexForState(AppListModel::STATE_START
);
58 if (from_page
!= start_page_index
&& to_page
!= start_page_index
)
61 views::View
* custom_page
= contents_view()->GetPageView(custom_page_index
);
62 gfx::Rect
custom_page_collapsed(
63 contents_view()->GetCustomPageCollapsedBounds());
64 gfx::Rect
custom_page_origin(GetOffscreenPageBounds(custom_page_index
));
65 gfx::Rect custom_page_rect
;
67 if (from_page
== start_page_index
) {
68 // When transitioning from start page -> any other page, move the custom
69 // page from collapsed to hidden. (This method is not used by the start page
70 // -> custom page transition.)
71 custom_page_rect
= gfx::Tween::RectValueBetween(
72 progress
, custom_page_collapsed
, custom_page_origin
);
74 // When transitioning from any page -> start page, move the custom page from
75 // hidden to collapsed.
76 custom_page_rect
= gfx::Tween::RectValueBetween(
77 progress
, custom_page_origin
, custom_page_collapsed
);
80 custom_page
->SetBoundsRect(custom_page_rect
);
83 void ContentsAnimator::UpdateSearchBoxForDefaultAnimation(double progress
,
86 if (!switches::IsExperimentalAppListEnabled())
89 // These are in ContentsView coordinates.
90 gfx::Rect
search_box_from(
91 contents_view()->GetSearchBoxBoundsForPageIndex(from_page
));
92 gfx::Rect
search_box_to(
93 contents_view()->GetSearchBoxBoundsForPageIndex(to_page
));
95 gfx::Rect search_box_rect
=
96 gfx::Tween::RectValueBetween(progress
, search_box_from
, search_box_to
);
98 views::View
* search_box
= contents_view()->GetSearchBoxView();
99 search_box
->GetWidget()->SetBounds(
100 contents_view()->ConvertRectToWidget(search_box_rect
));
103 void ContentsAnimator::ClipSearchResultsPageToOnscreenBounds(
105 const gfx::Rect
& current_bounds
,
106 const gfx::Rect
& onscreen_bounds
) {
107 int search_results_index
=
108 contents_view()->GetPageIndexForState(AppListModel::STATE_SEARCH_RESULTS
);
109 if (page_index
!= search_results_index
)
113 ->GetPageView(page_index
)
114 ->set_clip_insets(current_bounds
.InsetsFrom(onscreen_bounds
));
119 DefaultAnimator::DefaultAnimator(ContentsView
* contents_view
)
120 : ContentsAnimator(contents_view
) {
123 std::string
DefaultAnimator::NameForTests() const {
124 return "DefaultAnimator";
127 void DefaultAnimator::Update(double progress
, int from_page
, int to_page
) {
128 // Move the from page from 0 to its origin. Move the to page from its origin
130 gfx::Rect
from_page_onscreen(GetOnscreenPageBounds(from_page
));
131 gfx::Rect
to_page_onscreen(GetOnscreenPageBounds(to_page
));
132 gfx::Rect
from_page_origin(GetOffscreenPageBounds(from_page
));
133 gfx::Rect
to_page_origin(GetOffscreenPageBounds(to_page
));
134 gfx::Rect
from_page_rect(gfx::Tween::RectValueBetween(
135 progress
, from_page_onscreen
, from_page_origin
));
136 gfx::Rect
to_page_rect(
137 gfx::Tween::RectValueBetween(progress
, to_page_origin
, to_page_onscreen
));
139 contents_view()->GetPageView(from_page
)->SetBoundsRect(from_page_rect
);
140 ClipSearchResultsPageToOnscreenBounds(from_page
, from_page_rect
,
143 contents_view()->GetPageView(to_page
)->SetBoundsRect(to_page_rect
);
144 ClipSearchResultsPageToOnscreenBounds(to_page
, to_page_rect
,
147 UpdateCustomPageForDefaultAnimation(progress
, from_page
, to_page
);
148 UpdateSearchBoxForDefaultAnimation(progress
, from_page
, to_page
);
151 // StartToAppsAnimator
153 StartToAppsAnimator::StartToAppsAnimator(ContentsView
* contents_view
)
154 : ContentsAnimator(contents_view
) {
157 std::string
StartToAppsAnimator::NameForTests() const {
158 return "StartToAppsAnimator";
161 void StartToAppsAnimator::Update(double progress
,
164 // TODO(mgiuca): This is just a clone of DefaultAnimator's animation. Write a
165 // custom animation for the All Apps button on the Start page.
166 gfx::Rect
on_screen(contents_view()->GetDefaultContentsBounds());
167 gfx::Rect
from_page_origin(GetOffscreenPageBounds(start_page
));
168 gfx::Rect
to_page_origin(GetOffscreenPageBounds(apps_page
));
169 gfx::Rect
from_page_rect(
170 gfx::Tween::RectValueBetween(progress
, on_screen
, from_page_origin
));
171 gfx::Rect
to_page_rect(
172 gfx::Tween::RectValueBetween(progress
, to_page_origin
, on_screen
));
174 contents_view()->GetPageView(start_page
)->SetBoundsRect(from_page_rect
);
175 contents_view()->GetPageView(apps_page
)->SetBoundsRect(to_page_rect
);
177 UpdateCustomPageForDefaultAnimation(progress
, start_page
, apps_page
);
178 UpdateSearchBoxForDefaultAnimation(progress
, start_page
, apps_page
);
181 // StartToCustomAnimator
183 StartToCustomAnimator::StartToCustomAnimator(ContentsView
* contents_view
)
184 : ContentsAnimator(contents_view
) {
187 std::string
StartToCustomAnimator::NameForTests() const {
188 return "StartToCustomAnimator";
191 void StartToCustomAnimator::Update(double progress
,
194 gfx::Rect
start_page_on_screen(GetOnscreenPageBounds(start_page
));
195 gfx::Rect
custom_page_on_screen(GetOnscreenPageBounds(custom_page
));
196 gfx::Rect
start_page_origin(GetOffscreenPageBounds(start_page
));
197 gfx::Rect
custom_page_origin(contents_view()->GetCustomPageCollapsedBounds());
198 gfx::Rect
start_page_rect(gfx::Tween::RectValueBetween(
199 progress
, start_page_on_screen
, start_page_origin
));
200 gfx::Rect
custom_page_rect(gfx::Tween::RectValueBetween(
201 progress
, custom_page_origin
, custom_page_on_screen
));
203 contents_view()->GetPageView(start_page
)->SetBoundsRect(start_page_rect
);
204 contents_view()->GetPageView(custom_page
)->SetBoundsRect(custom_page_rect
);
206 UpdateSearchBoxForDefaultAnimation(progress
, start_page
, custom_page
);
209 } // namespace app_list