| Index: ui/app_list/views/contents_view.cc
|
| diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc
|
| index 4c40b448ed9e2e1ba302d9d53c0c9d7ba4b1e148..8bfcd12f9e0214764ded66dd185fb16a209b6cb2 100644
|
| --- a/ui/app_list/views/contents_view.cc
|
| +++ b/ui/app_list/views/contents_view.cc
|
| @@ -10,7 +10,6 @@
|
| #include "ui/app_list/app_list_constants.h"
|
| #include "ui/app_list/app_list_switches.h"
|
| #include "ui/app_list/app_list_view_delegate.h"
|
| -#include "ui/app_list/pagination_model.h"
|
| #include "ui/app_list/views/app_list_folder_view.h"
|
| #include "ui/app_list/views/app_list_main_view.h"
|
| #include "ui/app_list/views/apps_container_view.h"
|
| @@ -18,7 +17,6 @@
|
| #include "ui/app_list/views/search_result_list_view.h"
|
| #include "ui/app_list/views/start_page_view.h"
|
| #include "ui/events/event.h"
|
| -#include "ui/views/animation/bounds_animator.h"
|
| #include "ui/views/view_model.h"
|
| #include "ui/views/view_model_utils.h"
|
|
|
| @@ -40,8 +38,7 @@ ContentsView::ContentsView(AppListMainView* app_list_main_view,
|
| : search_results_view_(NULL),
|
| start_page_view_(NULL),
|
| app_list_main_view_(app_list_main_view),
|
| - view_model_(new views::ViewModel),
|
| - bounds_animator_(new views::BoundsAnimator(this)) {
|
| + view_model_(new views::ViewModel) {
|
| DCHECK(model);
|
|
|
| if (app_list::switches::IsExperimentalAppListEnabled()) {
|
| @@ -55,11 +52,14 @@ ContentsView::ContentsView(AppListMainView* app_list_main_view,
|
| }
|
|
|
| apps_container_view_ = new AppsContainerView(app_list_main_view, model);
|
| - active_page_ = AddLauncherPage(apps_container_view_, NAMED_PAGE_APPS);
|
| + int apps_page_index = AddLauncherPage(apps_container_view_, NAMED_PAGE_APPS);
|
|
|
| + pagination_model_.SelectPage(apps_page_index, false);
|
| + pagination_model_.AddObserver(this);
|
| }
|
|
|
| ContentsView::~ContentsView() {
|
| + pagination_model_.RemoveObserver(this);
|
| }
|
|
|
| void ContentsView::CancelDrag() {
|
| @@ -79,18 +79,23 @@ void ContentsView::SetDragAndDropHostOfCurrentAppList(
|
| }
|
|
|
| void ContentsView::SetActivePage(int page_index) {
|
| - if (active_page_ == page_index)
|
| + if (GetActivePageIndex() == page_index)
|
| return;
|
|
|
| SetActivePageInternal(page_index, false);
|
| }
|
|
|
| +int ContentsView::GetActivePageIndex() const {
|
| + // The active page is changed at the beginning of an animation, not the end.
|
| + return pagination_model_.SelectedTargetPage();
|
| +}
|
| +
|
| bool ContentsView::IsNamedPageActive(NamedPage named_page) const {
|
| std::map<NamedPage, int>::const_iterator it =
|
| named_page_to_view_.find(named_page);
|
| if (it == named_page_to_view_.end())
|
| return false;
|
| - return it->second == active_page_;
|
| + return it->second == GetActivePageIndex();
|
| }
|
|
|
| int ContentsView::GetPageIndexForNamedPage(NamedPage named_page) const {
|
| @@ -103,9 +108,14 @@ int ContentsView::GetPageIndexForNamedPage(NamedPage named_page) const {
|
| return it->second;
|
| }
|
|
|
| +int ContentsView::NumLauncherPages() const {
|
| + return pagination_model_.total_pages();
|
| +}
|
| +
|
| void ContentsView::SetActivePageInternal(int page_index,
|
| bool show_search_results) {
|
| - active_page_ = page_index;
|
| + // Start animating to the new page.
|
| + pagination_model_.SelectPage(page_index, true);
|
| ActivePageChanged(show_search_results);
|
| }
|
|
|
| @@ -127,8 +137,6 @@ void ContentsView::ActivePageChanged(bool show_search_results) {
|
|
|
| // Notify parent AppListMainView of the page change.
|
| app_list_main_view_->UpdateSearchBoxVisibility();
|
| -
|
| - AnimateToIdealBounds();
|
| }
|
|
|
| void ContentsView::ShowSearchResults(bool show) {
|
| @@ -146,49 +154,49 @@ bool ContentsView::IsShowingSearchResults() const {
|
| : IsNamedPageActive(NAMED_PAGE_SEARCH_RESULTS);
|
| }
|
|
|
| -void ContentsView::CalculateIdealBounds() {
|
| +void ContentsView::UpdatePageBounds() {
|
| gfx::Rect rect(GetContentsBounds());
|
| if (rect.IsEmpty())
|
| return;
|
|
|
| - if (app_list::switches::IsExperimentalAppListEnabled()) {
|
| - gfx::Rect incoming_target(rect);
|
| - gfx::Rect outgoing_target(rect);
|
| - outgoing_target.set_x(-outgoing_target.width());
|
| -
|
| - for (int i = 0; i < view_model_->view_size(); ++i) {
|
| - view_model_->set_ideal_bounds(
|
| - i, i == active_page_ ? incoming_target : outgoing_target);
|
| + // The bounds calculations will potentially be mid-transition (depending on
|
| + // the state of the PaginationModel).
|
| + int current_page = std::max(0, pagination_model_.selected_page());
|
| + int target_page = current_page;
|
| + double progress = 1;
|
| + if (pagination_model_.has_transition()) {
|
| + const PaginationModel::Transition& transition =
|
| + pagination_model_.transition();
|
| + if (pagination_model_.is_valid_page(transition.target_page)) {
|
| + target_page = transition.target_page;
|
| + progress = transition.progress;
|
| }
|
| - return;
|
| }
|
|
|
| - gfx::Rect container_frame(rect);
|
| - gfx::Rect results_frame(rect);
|
| -
|
| - // Offsets apps grid and result list based on |active_page_|.
|
| - // SearchResultListView is on top of apps grid. Visible view is left in
|
| - // visible area and invisible ones is put out of the visible area.
|
| - int contents_area_height = rect.height();
|
| - if (IsNamedPageActive(NAMED_PAGE_APPS))
|
| - results_frame.Offset(0, -contents_area_height);
|
| - else if (IsNamedPageActive(NAMED_PAGE_SEARCH_RESULTS))
|
| - container_frame.Offset(0, contents_area_height);
|
| - else
|
| - NOTREACHED() << "Page " << active_page_ << " invalid in current app list.";
|
| + gfx::Rect incoming_target(rect);
|
| + gfx::Rect outgoing_target(rect);
|
| + int dir = target_page > current_page ? -1 : 1;
|
|
|
| - view_model_->set_ideal_bounds(GetPageIndexForNamedPage(NAMED_PAGE_APPS),
|
| - container_frame);
|
| - view_model_->set_ideal_bounds(
|
| - GetPageIndexForNamedPage(NAMED_PAGE_SEARCH_RESULTS), results_frame);
|
| -}
|
| + if (app_list::switches::IsExperimentalAppListEnabled()) {
|
| + // The experimental app list transitions horizontally.
|
| + int page_width = rect.width();
|
| + int transition_offset = progress * page_width * dir;
|
|
|
| -void ContentsView::AnimateToIdealBounds() {
|
| - CalculateIdealBounds();
|
| - for (int i = 0; i < view_model_->view_size(); ++i) {
|
| - bounds_animator_->AnimateViewTo(view_model_->view_at(i),
|
| - view_model_->ideal_bounds(i));
|
| + outgoing_target.set_x(transition_offset);
|
| + incoming_target.set_x(dir < 0 ? transition_offset + page_width
|
| + : transition_offset - page_width);
|
| + } else {
|
| + // The normal app list transitions vertically.
|
| + int page_height = rect.height();
|
| + int transition_offset = progress * page_height * dir;
|
| +
|
| + outgoing_target.set_y(transition_offset);
|
| + incoming_target.set_y(dir < 0 ? transition_offset + page_height
|
| + : transition_offset - page_height);
|
| }
|
| +
|
| + view_model_->view_at(current_page)->SetBoundsRect(outgoing_target);
|
| + view_model_->view_at(target_page)->SetBoundsRect(incoming_target);
|
| }
|
|
|
| PaginationModel* ContentsView::GetAppsPaginationModel() {
|
| @@ -205,10 +213,19 @@ void ContentsView::Prerender() {
|
| apps_container_view_->apps_grid_view()->Prerender(selected_page);
|
| }
|
|
|
| +views::View* ContentsView::GetPageView(int index) {
|
| + return view_model_->view_at(index);
|
| +}
|
| +
|
| +void ContentsView::AddBlankPageForTesting() {
|
| + AddLauncherPage(new views::View);
|
| +}
|
| +
|
| int ContentsView::AddLauncherPage(views::View* view) {
|
| int page_index = view_model_->view_size();
|
| AddChildView(view);
|
| view_model_->Add(view, page_index);
|
| + pagination_model_.SetTotalPages(view_model_->view_size());
|
| return page_index;
|
| }
|
|
|
| @@ -231,12 +248,27 @@ gfx::Size ContentsView::GetPreferredSize() const {
|
| }
|
|
|
| void ContentsView::Layout() {
|
| - CalculateIdealBounds();
|
| - views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_);
|
| + // Immediately finish all current animations.
|
| + pagination_model_.FinishAnimation();
|
| +
|
| + // Move the current view onto the screen, and all other views off screen to
|
| + // the left. (Since we are not animating, we don't need to be careful about
|
| + // which side we place the off-screen views onto.)
|
| + gfx::Rect rect(GetContentsBounds());
|
| + if (rect.IsEmpty())
|
| + return;
|
| +
|
| + gfx::Rect offscreen_target(rect);
|
| + offscreen_target.set_x(-rect.width());
|
| +
|
| + for (int i = 0; i < view_model_->view_size(); ++i) {
|
| + view_model_->view_at(i)->SetBoundsRect(
|
| + i == pagination_model_.SelectedTargetPage() ? rect : offscreen_target);
|
| + }
|
| }
|
|
|
| bool ContentsView::OnKeyPressed(const ui::KeyEvent& event) {
|
| - return view_model_->view_at(active_page_)->OnKeyPressed(event);
|
| + return view_model_->view_at(GetActivePageIndex())->OnKeyPressed(event);
|
| }
|
|
|
| bool ContentsView::OnMouseWheel(const ui::MouseWheelEvent& event) {
|
| @@ -259,6 +291,19 @@ bool ContentsView::OnMouseWheel(const ui::MouseWheelEvent& event) {
|
| return false;
|
| }
|
|
|
| +void ContentsView::TotalPagesChanged() {
|
| +}
|
| +
|
| +void ContentsView::SelectedPageChanged(int old_selected, int new_selected) {
|
| +}
|
| +
|
| +void ContentsView::TransitionStarted() {
|
| +}
|
| +
|
| +void ContentsView::TransitionChanged() {
|
| + UpdatePageBounds();
|
| +}
|
| +
|
| void ContentsView::OnGestureEvent(ui::GestureEvent* event) {
|
| if (!IsNamedPageActive(NAMED_PAGE_APPS))
|
| return;
|
|
|