summaryrefslogtreecommitdiffstats
path: root/ui/app_list
diff options
context:
space:
mode:
authorcalamity <calamity@chromium.org>2015-03-22 21:22:18 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-23 04:23:12 +0000
commitbf77241a16c78814408fc513574c48a416ebe984 (patch)
tree1491f104e26749c44b81857ce6d349b3ae769a3b /ui/app_list
parent1dc69a362e8540b4fd96913b35865285c20704a7 (diff)
downloadchromium_src-bf77241a16c78814408fc513574c48a416ebe984.zip
chromium_src-bf77241a16c78814408fc513574c48a416ebe984.tar.gz
chromium_src-bf77241a16c78814408fc513574c48a416ebe984.tar.bz2
Refactor app list pages into a common base class and remove ContentsAnimator.
This CL refactors the app list pages into subclasses of AppListPage which provides methods that ContentsView uses to animate between app list States. This removes the need for ContentsAnimator and moves page animation behavior into each page's class. BUG=455059 Review URL: https://codereview.chromium.org/952803002 Cr-Commit-Position: refs/heads/master@{#321731}
Diffstat (limited to 'ui/app_list')
-rw-r--r--ui/app_list/BUILD.gn7
-rw-r--r--ui/app_list/app_list.gyp7
-rw-r--r--ui/app_list/views/app_list_main_view.cc1
-rw-r--r--ui/app_list/views/app_list_page.cc74
-rw-r--r--ui/app_list/views/app_list_page.h78
-rw-r--r--ui/app_list/views/app_list_view.cc8
-rw-r--r--ui/app_list/views/app_list_view_unittest.cc42
-rw-r--r--ui/app_list/views/apps_container_view.cc14
-rw-r--r--ui/app_list/views/apps_container_view.h9
-rw-r--r--ui/app_list/views/contents_animator.cc227
-rw-r--r--ui/app_list/views/contents_animator.h113
-rw-r--r--ui/app_list/views/contents_view.cc232
-rw-r--r--ui/app_list/views/contents_view.h67
-rw-r--r--ui/app_list/views/contents_view_unittest.cc78
-rw-r--r--ui/app_list/views/custom_launcher_page_view.cc50
-rw-r--r--ui/app_list/views/custom_launcher_page_view.h41
-rw-r--r--ui/app_list/views/search_result_page_view.cc36
-rw-r--r--ui/app_list/views/search_result_page_view.h11
-rw-r--r--ui/app_list/views/start_page_view.cc53
-rw-r--r--ui/app_list/views/start_page_view.h12
20 files changed, 480 insertions, 680 deletions
diff --git a/ui/app_list/BUILD.gn b/ui/app_list/BUILD.gn
index 2709e3a..a8f0831 100644
--- a/ui/app_list/BUILD.gn
+++ b/ui/app_list/BUILD.gn
@@ -109,6 +109,8 @@ component("app_list") {
"views/app_list_main_view.h",
"views/app_list_menu_views.cc",
"views/app_list_menu_views.h",
+ "views/app_list_page.cc",
+ "views/app_list_page.h",
"views/app_list_view.cc",
"views/app_list_view.h",
"views/app_list_view_observer.h",
@@ -120,10 +122,10 @@ component("app_list") {
"views/apps_grid_view_folder_delegate.h",
"views/cached_label.cc",
"views/cached_label.h",
- "views/contents_animator.cc",
- "views/contents_animator.h",
"views/contents_view.cc",
"views/contents_view.h",
+ "views/custom_launcher_page_view.cc",
+ "views/custom_launcher_page_view.h",
"views/folder_background_view.cc",
"views/folder_background_view.h",
"views/folder_header_view.cc",
@@ -295,7 +297,6 @@ test("app_list_unittests") {
"views/app_list_main_view_unittest.cc",
"views/app_list_view_unittest.cc",
"views/apps_grid_view_unittest.cc",
- "views/contents_view_unittest.cc",
"views/folder_header_view_unittest.cc",
"views/search_box_view_unittest.cc",
"views/search_result_list_view_unittest.cc",
diff --git a/ui/app_list/app_list.gyp b/ui/app_list/app_list.gyp
index d6c062d..af31558 100644
--- a/ui/app_list/app_list.gyp
+++ b/ui/app_list/app_list.gyp
@@ -125,6 +125,8 @@
'views/app_list_main_view.h',
'views/app_list_menu_views.cc',
'views/app_list_menu_views.h',
+ 'views/app_list_page.cc',
+ 'views/app_list_page.h',
'views/app_list_view.cc',
'views/app_list_view.h',
'views/app_list_view_observer.h',
@@ -136,10 +138,10 @@
'views/apps_grid_view_folder_delegate.h',
'views/cached_label.cc',
'views/cached_label.h',
- 'views/contents_animator.cc',
- 'views/contents_animator.h',
'views/contents_view.cc',
'views/contents_view.h',
+ 'views/custom_launcher_page_view.cc',
+ 'views/custom_launcher_page_view.h',
'views/folder_background_view.cc',
'views/folder_background_view.h',
'views/folder_header_view.cc',
@@ -273,7 +275,6 @@
'views/app_list_main_view_unittest.cc',
'views/app_list_view_unittest.cc',
'views/apps_grid_view_unittest.cc',
- 'views/contents_view_unittest.cc',
'views/folder_header_view_unittest.cc',
'views/search_box_view_unittest.cc',
'views/search_result_list_view_unittest.cc',
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index aa45d63..986b477 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -25,6 +25,7 @@
#include "ui/app_list/views/apps_container_view.h"
#include "ui/app_list/views/apps_grid_view.h"
#include "ui/app_list/views/contents_view.h"
+#include "ui/app_list/views/custom_launcher_page_view.h"
#include "ui/app_list/views/search_box_view.h"
#include "ui/app_list/views/search_result_page_view.h"
#include "ui/app_list/views/start_page_view.h"
diff --git a/ui/app_list/views/app_list_page.cc b/ui/app_list/views/app_list_page.cc
new file mode 100644
index 0000000..8a7b6f3
--- /dev/null
+++ b/ui/app_list/views/app_list_page.cc
@@ -0,0 +1,74 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/app_list/views/app_list_page.h"
+
+#include "ui/app_list/views/contents_view.h"
+
+namespace {
+
+// The default z height for the search box.
+const int kDefaultSearchBoxZHeight = 2;
+}
+
+namespace app_list {
+
+AppListPage::AppListPage() : contents_view_(nullptr) {
+}
+
+AppListPage::~AppListPage() {
+}
+
+void AppListPage::OnShown() {
+}
+
+void AppListPage::OnWillBeShown() {
+}
+
+void AppListPage::OnHidden() {
+}
+
+void AppListPage::OnWillBeHidden() {
+}
+
+void AppListPage::OnAnimationUpdated(double progress,
+ AppListModel::State from_state,
+ AppListModel::State to_state) {
+}
+
+gfx::Rect AppListPage::GetSearchBoxBounds() const {
+ DCHECK(contents_view_);
+ return contents_view_->GetDefaultSearchBoxBounds();
+}
+
+int AppListPage::GetSearchBoxZHeight() const {
+ return kDefaultSearchBoxZHeight;
+}
+
+gfx::Rect AppListPage::GetAboveContentsOffscreenBounds(
+ const gfx::Size& size) const {
+ gfx::Rect rect(size);
+ rect.set_y(-rect.height());
+ return rect;
+}
+
+gfx::Rect AppListPage::GetBelowContentsOffscreenBounds(
+ const gfx::Size& size) const {
+ DCHECK(contents_view_);
+ gfx::Rect rect(size);
+ rect.set_y(contents_view_->GetContentsBounds().height());
+ return rect;
+}
+
+gfx::Rect AppListPage::GetFullContentsBounds() const {
+ DCHECK(contents_view_);
+ return contents_view_->GetContentsBounds();
+}
+
+gfx::Rect AppListPage::GetDefaultContentsBounds() const {
+ DCHECK(contents_view_);
+ return contents_view_->GetDefaultContentsBounds();
+}
+
+} // namespace app_list
diff --git a/ui/app_list/views/app_list_page.h b/ui/app_list/views/app_list_page.h
new file mode 100644
index 0000000..08ecf25
--- /dev/null
+++ b/ui/app_list/views/app_list_page.h
@@ -0,0 +1,78 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_APP_LIST_VIEWS_APP_LIST_PAGE_H_
+#define UI_APP_LIST_VIEWS_APP_LIST_PAGE_H_
+
+#include "ui/app_list/app_list_export.h"
+#include "ui/app_list/app_list_model.h"
+#include "ui/views/view.h"
+
+namespace app_list {
+
+class ContentsView;
+
+class APP_LIST_EXPORT AppListPage : public views::View {
+ public:
+ // Triggered when the page is about to be shown.
+ virtual void OnWillBeShown();
+
+ // Triggered after the page has been shown.
+ virtual void OnShown();
+
+ // Triggered when the page is about to be hidden.
+ virtual void OnWillBeHidden();
+
+ // Triggered after the page has been hidden.
+ virtual void OnHidden();
+
+ // Triggered after the animation has updated.
+ virtual void OnAnimationUpdated(double progress,
+ AppListModel::State from_state,
+ AppListModel::State to_state);
+
+ // Returns where this page should move to when the given state is active.
+ virtual gfx::Rect GetPageBoundsForState(AppListModel::State state) const = 0;
+
+ // Returns where the search box should be when this page is shown. Is at the
+ // top of the app list by default, in the contents view's coordinate space.
+ virtual gfx::Rect GetSearchBoxBounds() const;
+
+ // Returns the z height of the search box for this page.
+ virtual int GetSearchBoxZHeight() const;
+
+ void set_contents_view(ContentsView* contents_view) {
+ contents_view_ = contents_view;
+ }
+
+ protected:
+ AppListPage();
+ ~AppListPage() override;
+
+ // Returns the area above the contents view, given the desired size of this
+ // page, in the contents view's coordinate space.
+ gfx::Rect GetAboveContentsOffscreenBounds(const gfx::Size& size) const;
+
+ // Returns the area below the contents view, given the desired size of this
+ // page, in the contents view's coordinate space.
+ gfx::Rect GetBelowContentsOffscreenBounds(const gfx::Size& size) const;
+
+ // Returns the entire bounds of the contents view, in the contents view's
+ // coordinate space.
+ gfx::Rect GetFullContentsBounds() const;
+
+ // Returns the default bounds of pages inside the contents view, in the
+ // contents view's coordinate space. This is the area of the contents view
+ // below the search box.
+ gfx::Rect GetDefaultContentsBounds() const;
+
+ private:
+ ContentsView* contents_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppListPage);
+};
+
+} // namespace app_list
+
+#endif // UI_APP_LIST_VIEWS_APP_LIST_PAGE_H_
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index 216abf4..a6aa8eb 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -22,6 +22,7 @@
#include "ui/app_list/views/app_list_view_observer.h"
#include "ui/app_list/views/apps_container_view.h"
#include "ui/app_list/views/contents_view.h"
+#include "ui/app_list/views/custom_launcher_page_view.h"
#include "ui/app_list/views/search_box_view.h"
#include "ui/app_list/views/speech_view.h"
#include "ui/app_list/views/start_page_view.h"
@@ -366,8 +367,11 @@ bool AppListView::ShouldDescendIntoChildForEventHandling(
// While on the start page, don't descend into the custom launcher page. Since
// the only valid action is to open it.
ContentsView* contents_view = app_list_main_view_->contents_view();
- if (contents_view->GetActiveState() == AppListModel::STATE_START)
- return !contents_view->GetCustomPageCollapsedBounds().Contains(location);
+ if (contents_view->custom_page_view() &&
+ contents_view->GetActiveState() == AppListModel::STATE_START)
+ return !contents_view->custom_page_view()
+ ->GetCollapsedLauncherPageBounds()
+ .Contains(location);
return views::BubbleDelegateView::ShouldDescendIntoChildForEventHandling(
child, location);
diff --git a/ui/app_list/views/app_list_view_unittest.cc b/ui/app_list/views/app_list_view_unittest.cc
index dde70081..a8fc4e0 100644
--- a/ui/app_list/views/app_list_view_unittest.cc
+++ b/ui/app_list/views/app_list_view_unittest.cc
@@ -136,7 +136,7 @@ class AppListViewTestContext {
// and returns false on failure.
bool SetAppListState(AppListModel::State state);
- // Returns whether the app list showing |state|.
+ // Returns true if all of the pages are in their correct position for |state|.
bool IsStateShown(AppListModel::State state);
// Shows the app list and waits until a paint occurs.
@@ -241,12 +241,11 @@ bool AppListViewTestContext::SetAppListState(AppListModel::State state) {
bool AppListViewTestContext::IsStateShown(AppListModel::State state) {
ContentsView* contents_view = view_->app_list_main_view()->contents_view();
- int index = contents_view->GetPageIndexForState(state);
bool success = true;
for (int i = 0; i < contents_view->NumLauncherPages(); ++i) {
success = success &&
- (i == index) == (contents_view->GetOnscreenPageBounds(i) ==
- contents_view->GetPageView(i)->bounds());
+ (contents_view->GetPageView(i)->GetPageBoundsForState(state) ==
+ contents_view->GetPageView(i)->bounds());
}
return success && state == delegate_->GetTestModel()->state();
}
@@ -509,50 +508,23 @@ void AppListViewTestContext::RunPageSwitchingAnimationTest() {
ContentsView* contents_view = main_view->contents_view();
- int start_page_index =
- contents_view->GetPageIndexForState(AppListModel::STATE_START);
- int search_results_page_index =
- contents_view->GetPageIndexForState(AppListModel::STATE_SEARCH_RESULTS);
- int apps_page_index =
- contents_view->GetPageIndexForState(AppListModel::STATE_APPS);
-
contents_view->SetActiveState(AppListModel::STATE_START);
contents_view->Layout();
- EXPECT_EQ(contents_view->GetOnscreenPageBounds(start_page_index),
- contents_view->GetPageView(start_page_index)->bounds());
- EXPECT_NE(contents_view->GetOnscreenPageBounds(search_results_page_index),
- contents_view->GetPageView(search_results_page_index)->bounds());
- EXPECT_NE(contents_view->GetOnscreenPageBounds(apps_page_index),
- contents_view->GetPageView(apps_page_index)->bounds());
+ IsStateShown(AppListModel::STATE_START);
// Change pages. View should not have moved without Layout().
contents_view->SetActiveState(AppListModel::STATE_SEARCH_RESULTS);
- EXPECT_EQ(contents_view->GetOnscreenPageBounds(start_page_index),
- contents_view->GetPageView(start_page_index)->bounds());
- EXPECT_NE(contents_view->GetOnscreenPageBounds(search_results_page_index),
- contents_view->GetPageView(search_results_page_index)->bounds());
- EXPECT_NE(contents_view->GetOnscreenPageBounds(apps_page_index),
- contents_view->GetPageView(apps_page_index)->bounds());
+ IsStateShown(AppListModel::STATE_START);
// Change to a third page. This queues up the second animation behind the
// first.
contents_view->SetActiveState(AppListModel::STATE_APPS);
- EXPECT_EQ(contents_view->GetOnscreenPageBounds(start_page_index),
- contents_view->GetPageView(start_page_index)->bounds());
- EXPECT_NE(contents_view->GetOnscreenPageBounds(search_results_page_index),
- contents_view->GetPageView(search_results_page_index)->bounds());
- EXPECT_NE(contents_view->GetOnscreenPageBounds(apps_page_index),
- contents_view->GetPageView(apps_page_index)->bounds());
+ IsStateShown(AppListModel::STATE_START);
// Call Layout(). Should jump to the third page.
contents_view->Layout();
- EXPECT_NE(contents_view->GetOnscreenPageBounds(start_page_index),
- contents_view->GetPageView(start_page_index)->bounds());
- EXPECT_NE(contents_view->GetOnscreenPageBounds(search_results_page_index),
- contents_view->GetPageView(search_results_page_index)->bounds());
- EXPECT_EQ(contents_view->GetOnscreenPageBounds(apps_page_index),
- contents_view->GetPageView(apps_page_index)->bounds());
+ IsStateShown(AppListModel::STATE_APPS);
}
Close();
diff --git a/ui/app_list/views/apps_container_view.cc b/ui/app_list/views/apps_container_view.cc
index 6cc0fbc..38d55b6 100644
--- a/ui/app_list/views/apps_container_view.cc
+++ b/ui/app_list/views/apps_container_view.cc
@@ -144,6 +144,20 @@ bool AppsContainerView::OnKeyPressed(const ui::KeyEvent& event) {
return app_list_folder_view_->OnKeyPressed(event);
}
+void AppsContainerView::OnWillBeShown() {
+ apps_grid_view()->ClearAnySelectedView();
+ app_list_folder_view()->items_grid_view()->ClearAnySelectedView();
+}
+
+gfx::Rect AppsContainerView::GetPageBoundsForState(
+ AppListModel::State state) const {
+ gfx::Rect onscreen_bounds = GetDefaultContentsBounds();
+ if (state == AppListModel::STATE_APPS)
+ return onscreen_bounds;
+
+ return GetBelowContentsOffscreenBounds(onscreen_bounds.size());
+}
+
void AppsContainerView::OnTopIconAnimationsComplete() {
--top_icon_animation_pending_count_;
diff --git a/ui/app_list/views/apps_container_view.h b/ui/app_list/views/apps_container_view.h
index 2ba68a2..966e57f 100644
--- a/ui/app_list/views/apps_container_view.h
+++ b/ui/app_list/views/apps_container_view.h
@@ -8,8 +8,8 @@
#include <vector>
#include "ui/app_list/app_list_folder_item.h"
+#include "ui/app_list/views/app_list_page.h"
#include "ui/app_list/views/top_icon_animation_view.h"
-#include "ui/views/view.h"
namespace gfx {
class Rect;
@@ -29,8 +29,7 @@ class FolderBackgroundView;
// AppsContainerView contains a root level AppsGridView to render the root level
// app items, and a AppListFolderView to render the app items inside the
// active folder. Only one if them is visible to user at any time.
-class AppsContainerView : public views::View,
- public TopIconAnimationObserver {
+class AppsContainerView : public AppListPage, public TopIconAnimationObserver {
public:
AppsContainerView(AppListMainView* app_list_main_view,
AppListModel* model);
@@ -66,6 +65,10 @@ class AppsContainerView : public views::View,
void Layout() override;
bool OnKeyPressed(const ui::KeyEvent& event) override;
+ // AppListPage overrides:
+ void OnWillBeShown() override;
+ gfx::Rect GetPageBoundsForState(AppListModel::State state) const override;
+
// TopIconAnimationObserver overrides:
void OnTopIconAnimationsComplete() override;
diff --git a/ui/app_list/views/contents_animator.cc b/ui/app_list/views/contents_animator.cc
deleted file mode 100644
index 0c0bbfa..0000000
--- a/ui/app_list/views/contents_animator.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/app_list/views/contents_animator.h"
-
-#include "ui/app_list/app_list_constants.h"
-#include "ui/app_list/app_list_switches.h"
-#include "ui/app_list/views/app_list_main_view.h"
-#include "ui/app_list/views/contents_view.h"
-#include "ui/app_list/views/search_box_view.h"
-#include "ui/app_list/views/start_page_view.h"
-#include "ui/gfx/animation/tween.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/shadow_value.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
-
-namespace app_list {
-
-namespace {
-
-gfx::ShadowValue GetSearchBoxShadowForState(AppListModel::State state) {
- return GetShadowForZHeight(state == AppListModel::STATE_SEARCH_RESULTS ? 1
- : 2);
-}
-
-} // namespace
-
-// ContentsAnimator
-
-ContentsAnimator::ContentsAnimator(ContentsView* contents_view)
- : contents_view_(contents_view) {
-}
-
-ContentsAnimator::~ContentsAnimator() {
-}
-
-void ContentsAnimator::UpdateCustomPageForDefaultAnimation(double progress,
- int from_page,
- int to_page) const {
- int custom_page_index = contents_view()->GetPageIndexForState(
- AppListModel::STATE_CUSTOM_LAUNCHER_PAGE);
- if (custom_page_index < 0)
- return;
-
- int start_page_index =
- contents_view()->GetPageIndexForState(AppListModel::STATE_START);
- if (from_page != start_page_index && to_page != start_page_index)
- return;
-
- views::View* custom_page = contents_view()->GetPageView(custom_page_index);
- gfx::Rect custom_page_collapsed(
- contents_view()->GetCustomPageCollapsedBounds());
- gfx::Rect custom_page_origin(
- contents_view()->GetOffscreenPageBounds(custom_page_index));
- gfx::Rect custom_page_rect;
-
- if (from_page == start_page_index) {
- // When transitioning from start page -> any other page, move the custom
- // page from collapsed to hidden. (This method is not used by the start page
- // -> custom page transition.)
- custom_page_rect = gfx::Tween::RectValueBetween(
- progress, custom_page_collapsed, custom_page_origin);
- } else {
- // When transitioning from any page -> start page, move the custom page from
- // hidden to collapsed.
- custom_page_rect = gfx::Tween::RectValueBetween(
- progress, custom_page_origin, custom_page_collapsed);
- }
-
- custom_page->SetBoundsRect(custom_page_rect);
-}
-
-void ContentsAnimator::UpdateSearchBoxForDefaultAnimation(double progress,
- int from_page,
- int to_page) const {
- if (!switches::IsExperimentalAppListEnabled())
- return;
-
- // These are in ContentsView coordinates.
- gfx::Rect search_box_from(
- contents_view()->GetSearchBoxBoundsForPageIndex(from_page));
- gfx::Rect search_box_to(
- contents_view()->GetSearchBoxBoundsForPageIndex(to_page));
-
- gfx::Rect search_box_rect =
- gfx::Tween::RectValueBetween(progress, search_box_from, search_box_to);
-
- AppListModel::State from_state =
- contents_view()->GetStateForPageIndex(from_page);
- AppListModel::State to_state = contents_view()->GetStateForPageIndex(to_page);
-
- gfx::ShadowValue original_shadow = GetSearchBoxShadowForState(from_state);
- gfx::ShadowValue target_shadow = GetSearchBoxShadowForState(to_state);
-
- SearchBoxView* search_box = contents_view()->GetSearchBoxView();
- gfx::Vector2d offset(gfx::Tween::LinearIntValueBetween(
- progress, original_shadow.x(), target_shadow.x()),
- gfx::Tween::LinearIntValueBetween(
- progress, original_shadow.y(), target_shadow.y()));
- search_box->SetShadow(gfx::ShadowValue(
- offset, gfx::Tween::LinearIntValueBetween(
- progress, original_shadow.blur(), target_shadow.blur()),
- gfx::Tween::ColorValueBetween(progress, original_shadow.color(),
- target_shadow.color())));
-
- search_box->GetWidget()->SetBounds(
- search_box->GetViewBoundsForSearchBoxContentsBounds(
- contents_view()->ConvertRectToWidget(search_box_rect)));
-}
-
-void ContentsAnimator::ClipSearchResultsPageToOnscreenBounds(
- int page_index,
- const gfx::Rect& current_bounds,
- const gfx::Rect& onscreen_bounds) {
- int search_results_index =
- contents_view()->GetPageIndexForState(AppListModel::STATE_SEARCH_RESULTS);
- if (page_index != search_results_index)
- return;
-
- contents_view()
- ->GetPageView(page_index)
- ->set_clip_insets(current_bounds.InsetsFrom(onscreen_bounds));
-}
-
-// DefaultAnimator
-
-DefaultAnimator::DefaultAnimator(ContentsView* contents_view)
- : ContentsAnimator(contents_view) {
-}
-
-std::string DefaultAnimator::NameForTests() const {
- return "DefaultAnimator";
-}
-
-void DefaultAnimator::Update(double progress, int from_page, int to_page) {
- // Move the from page from 0 to its origin. Move the to page from its origin
- // to 0.
- gfx::Rect from_page_onscreen(
- contents_view()->GetOnscreenPageBounds(from_page));
- gfx::Rect to_page_onscreen(contents_view()->GetOnscreenPageBounds(to_page));
- gfx::Rect from_page_origin(
- contents_view()->GetOffscreenPageBounds(from_page));
- gfx::Rect to_page_origin(contents_view()->GetOffscreenPageBounds(to_page));
- gfx::Rect from_page_rect(gfx::Tween::RectValueBetween(
- progress, from_page_onscreen, from_page_origin));
- gfx::Rect to_page_rect(
- gfx::Tween::RectValueBetween(progress, to_page_origin, to_page_onscreen));
-
- contents_view()->GetPageView(from_page)->SetBoundsRect(from_page_rect);
- ClipSearchResultsPageToOnscreenBounds(from_page, from_page_rect,
- from_page_onscreen);
-
- contents_view()->GetPageView(to_page)->SetBoundsRect(to_page_rect);
- ClipSearchResultsPageToOnscreenBounds(to_page, to_page_rect,
- to_page_onscreen);
-
- UpdateCustomPageForDefaultAnimation(progress, from_page, to_page);
- UpdateSearchBoxForDefaultAnimation(progress, from_page, to_page);
-}
-
-// StartToAppsAnimator
-
-StartToAppsAnimator::StartToAppsAnimator(ContentsView* contents_view)
- : ContentsAnimator(contents_view) {
-}
-
-std::string StartToAppsAnimator::NameForTests() const {
- return "StartToAppsAnimator";
-}
-
-void StartToAppsAnimator::Update(double progress,
- int start_page,
- int apps_page) {
- // TODO(mgiuca): This is just a clone of DefaultAnimator's animation. Write a
- // custom animation for the All Apps button on the Start page.
- gfx::Rect from_page_onscreen(
- contents_view()->GetOnscreenPageBounds(start_page));
- gfx::Rect to_page_onscreen(contents_view()->GetOnscreenPageBounds(apps_page));
- gfx::Rect from_page_origin(
- contents_view()->GetOffscreenPageBounds(start_page));
- gfx::Rect to_page_origin(contents_view()->GetOffscreenPageBounds(apps_page));
- gfx::Rect from_page_rect(gfx::Tween::RectValueBetween(
- progress, from_page_onscreen, from_page_origin));
- gfx::Rect to_page_rect(
- gfx::Tween::RectValueBetween(progress, to_page_origin, to_page_onscreen));
-
- contents_view()->GetPageView(start_page)->SetBoundsRect(from_page_rect);
- contents_view()->GetPageView(apps_page)->SetBoundsRect(to_page_rect);
-
- UpdateCustomPageForDefaultAnimation(progress, start_page, apps_page);
- UpdateSearchBoxForDefaultAnimation(progress, start_page, apps_page);
-}
-
-// StartToCustomAnimator
-
-StartToCustomAnimator::StartToCustomAnimator(ContentsView* contents_view)
- : ContentsAnimator(contents_view) {
-}
-
-std::string StartToCustomAnimator::NameForTests() const {
- return "StartToCustomAnimator";
-}
-
-void StartToCustomAnimator::Update(double progress,
- int start_page,
- int custom_page) {
- gfx::Rect start_page_on_screen(
- contents_view()->GetOnscreenPageBounds(start_page));
- gfx::Rect custom_page_on_screen(
- contents_view()->GetOnscreenPageBounds(custom_page));
- gfx::Rect start_page_origin(
- contents_view()->GetOffscreenPageBounds(start_page));
- gfx::Rect custom_page_origin(contents_view()->GetCustomPageCollapsedBounds());
- gfx::Rect start_page_rect(gfx::Tween::RectValueBetween(
- progress, start_page_on_screen, start_page_origin));
- gfx::Rect custom_page_rect(gfx::Tween::RectValueBetween(
- progress, custom_page_origin, custom_page_on_screen));
-
- contents_view()->GetPageView(start_page)->SetBoundsRect(start_page_rect);
- contents_view()->GetPageView(custom_page)->SetBoundsRect(custom_page_rect);
-
- UpdateSearchBoxForDefaultAnimation(progress, start_page, custom_page);
-}
-
-} // namespace app_list
diff --git a/ui/app_list/views/contents_animator.h b/ui/app_list/views/contents_animator.h
deleted file mode 100644
index a643afd..0000000
--- a/ui/app_list/views/contents_animator.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_APP_LIST_VIEWS_CONTENTS_ANIMATOR_H_
-#define UI_APP_LIST_VIEWS_CONTENTS_ANIMATOR_H_
-
-#include <string>
-
-#include "base/macros.h"
-
-namespace gfx {
-class Rect;
-}
-
-namespace app_list {
-
-class ContentsView;
-
-// Manages an animation between two specific pages of the ContentsView.
-// Different subclasses implement different animations, so we can have a custom
-// animation for each pair of pages. Animations are reversible (if A -> B is
-// implemented, B -> A will implicitly be the inverse animation).
-class ContentsAnimator {
- public:
- explicit ContentsAnimator(ContentsView* contents_view);
-
- virtual ~ContentsAnimator();
-
- // Gets the name of the animator, for testing.
- virtual std::string NameForTests() const = 0;
-
- // Updates the state of the ContentsView. |progress| is the amount of progress
- // made on the animation, where 0.0 is the beginning and 1.0 is the end. The
- // animation should be linear (not eased in or out) so that it can be played
- // forwards or reversed. Easing will be applied by the PaginationModel.
- virtual void Update(double progress, int from_page, int to_page) = 0;
-
- protected:
- const ContentsView* contents_view() const { return contents_view_; }
-
- // Updates the position of the custom launcher page view (if it exists), in
- // the default way for start page <-> other page transitions. This places it
- // into collapsed state on the start page, and hidden on any other page. Any
- // other behaviour should be implemented with a custom animator. |progress|,
- // |from_page| and |to_page| are parameters from Update().
- void UpdateCustomPageForDefaultAnimation(double progress,
- int from_page,
- int to_page) const;
-
- // Updates the position of the search box view, placing it in the correct
- // position for the transition from |from_page| to |to_page|.
- void UpdateSearchBoxForDefaultAnimation(double progress,
- int from_page,
- int to_page) const;
-
- // Clips the drawing of the search results page to its onscreen bounds.
- void ClipSearchResultsPageToOnscreenBounds(int page_index,
- const gfx::Rect& current_bounds,
- const gfx::Rect& onscreen_bounds);
-
- private:
- ContentsView* contents_view_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentsAnimator);
-};
-
-// Simple animator that slides pages in and out vertically. Appropriate for any
-// page pair.
-class DefaultAnimator : public ContentsAnimator {
- public:
- explicit DefaultAnimator(ContentsView* contents_view);
-
- ~DefaultAnimator() override {}
-
- // ContentsAnimator overrides:
- std::string NameForTests() const override;
- void Update(double progress, int from_page, int to_page) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DefaultAnimator);
-};
-
-// Animator between the start page and apps grid page.
-class StartToAppsAnimator : public ContentsAnimator {
- public:
- explicit StartToAppsAnimator(ContentsView* contents_view);
-
- ~StartToAppsAnimator() override {}
-
- // ContentsAnimator overrides:
- std::string NameForTests() const override;
- void Update(double progress, int start_page, int apps_page) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(StartToAppsAnimator);
-};
-
-// Animator from start page to custom page.
-class StartToCustomAnimator : public ContentsAnimator {
- public:
- explicit StartToCustomAnimator(ContentsView* contents_view);
-
- std::string NameForTests() const override;
- void Update(double progress, int start_page, int custom_page) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(StartToCustomAnimator);
-};
-
-} // namespace app_list
-
-#endif // UI_APP_LIST_VIEWS_CONTENTS_ANIMATOR_H_
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc
index 623b391..9db4696 100644
--- a/ui/app_list/views/contents_view.cc
+++ b/ui/app_list/views/contents_view.cc
@@ -15,7 +15,7 @@
#include "ui/app_list/views/app_list_main_view.h"
#include "ui/app_list/views/apps_container_view.h"
#include "ui/app_list/views/apps_grid_view.h"
-#include "ui/app_list/views/contents_animator.h"
+#include "ui/app_list/views/custom_launcher_page_view.h"
#include "ui/app_list/views/search_box_view.h"
#include "ui/app_list/views/search_result_list_view.h"
#include "ui/app_list/views/search_result_page_view.h"
@@ -24,7 +24,6 @@
#include "ui/events/event.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/views/view_model.h"
-#include "ui/views/view_model_utils.h"
#include "ui/views/widget/widget.h"
namespace app_list {
@@ -35,7 +34,6 @@ ContentsView::ContentsView(AppListMainView* app_list_main_view)
start_page_view_(nullptr),
custom_page_view_(nullptr),
app_list_main_view_(app_list_main_view),
- view_model_(new views::ViewModel),
page_before_search_(0) {
pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs,
kOverscrollPageTransitionDurationMs);
@@ -61,11 +59,12 @@ void ContentsView::Init(AppListModel* model) {
// Only the first launcher page is considered to represent
// STATE_CUSTOM_LAUNCHER_PAGE.
if (it == custom_page_views.begin()) {
- custom_page_view_ = *it;
+ custom_page_view_ = new CustomLauncherPageView(*it);
- AddLauncherPage(*it, AppListModel::STATE_CUSTOM_LAUNCHER_PAGE);
+ AddLauncherPage(custom_page_view_,
+ AppListModel::STATE_CUSTOM_LAUNCHER_PAGE);
} else {
- AddLauncherPage(*it);
+ AddLauncherPage(new CustomLauncherPageView(*it));
}
}
@@ -101,18 +100,15 @@ void ContentsView::Init(AppListModel* model) {
page_before_search_ = initial_page_index;
// Must only call SetTotalPages once all the launcher pages have been added
// (as it will trigger a SelectedPageChanged call).
- pagination_model_.SetTotalPages(view_model_->view_size());
+ pagination_model_.SetTotalPages(app_list_pages_.size());
+
+ // Page 0 is selected by SetTotalPages and needs to be 'hidden' when selecting
+ // the initial page.
+ app_list_pages_[GetActivePageIndex()]->OnWillBeHidden();
+
pagination_model_.SelectPage(initial_page_index, false);
ActivePageChanged();
-
- // Populate the contents animators.
- AddAnimator(AppListModel::STATE_START, AppListModel::STATE_APPS,
- scoped_ptr<ContentsAnimator>(new StartToAppsAnimator(this)));
- AddAnimator(AppListModel::STATE_START,
- AppListModel::STATE_CUSTOM_LAUNCHER_PAGE,
- scoped_ptr<ContentsAnimator>(new StartToCustomAnimator(this)));
- default_animator_.reset(new DefaultAnimator(this));
}
void ContentsView::CancelDrag() {
@@ -188,6 +184,9 @@ void ContentsView::SetActiveStateInternal(int page_index,
if (!show_search_results)
page_before_search_ = page_index;
+
+ app_list_pages_[GetActivePageIndex()]->OnWillBeHidden();
+
// Start animating to the new page.
pagination_model_.SelectPage(page_index, animate);
ActivePageChanged();
@@ -199,14 +198,13 @@ void ContentsView::SetActiveStateInternal(int page_index,
void ContentsView::ActivePageChanged() {
AppListModel::State state = AppListModel::INVALID_STATE;
- // TODO(calamity): This does not report search results being shown in the
- // experimental app list as a boolean is currently used to indicate whether
- // search results are showing. See http://crbug.com/427787/.
std::map<int, AppListModel::State>::const_iterator it =
- view_to_state_.find(pagination_model_.SelectedTargetPage());
+ view_to_state_.find(GetActivePageIndex());
if (it != view_to_state_.end())
state = it->second;
+ app_list_pages_[GetActivePageIndex()]->OnWillBeShown();
+
app_list_main_view_->model()->SetState(state);
if (switches::IsExperimentalAppListEnabled()) {
@@ -223,14 +221,6 @@ void ContentsView::ActivePageChanged() {
}
app_list_main_view_->search_box_view()->ResetTabFocus(false);
- apps_container_view_->apps_grid_view()->ClearAnySelectedView();
- apps_container_view_->app_list_folder_view()->items_grid_view()
- ->ClearAnySelectedView();
-
- if (custom_page_view_) {
- custom_page_view_->SetFocusable(state ==
- AppListModel::STATE_CUSTOM_LAUNCHER_PAGE);
- }
}
void ContentsView::ShowSearchResults(bool show) {
@@ -275,48 +265,66 @@ void ContentsView::UpdatePageBounds() {
NotifyCustomLauncherPageAnimationChanged(progress, current_page, target_page);
- bool reverse;
- ContentsAnimator* animator =
- GetAnimatorForTransition(current_page, target_page, &reverse);
+ AppListModel::State current_state = GetStateForPageIndex(current_page);
+ AppListModel::State target_state = GetStateForPageIndex(target_page);
- // Animate linearly (the PaginationModel handles easing).
- if (reverse)
- animator->Update(1 - progress, target_page, current_page);
- else
- animator->Update(progress, current_page, target_page);
-}
+ // Update app list pages.
+ for (AppListPage* page : app_list_pages_) {
+ page->OnAnimationUpdated(progress, current_state, target_state);
-PaginationModel* ContentsView::GetAppsPaginationModel() {
- return apps_container_view_->apps_grid_view()->pagination_model();
-}
+ gfx::Rect to_rect = page->GetPageBoundsForState(target_state);
+ gfx::Rect from_rect = page->GetPageBoundsForState(current_state);
+ if (from_rect == to_rect)
+ continue;
-void ContentsView::AddAnimator(AppListModel::State from_state,
- AppListModel::State to_state,
- scoped_ptr<ContentsAnimator> animator) {
- int from_page = GetPageIndexForState(from_state);
- int to_page = GetPageIndexForState(to_state);
- contents_animators_.insert(
- std::make_pair(std::make_pair(from_page, to_page),
- linked_ptr<ContentsAnimator>(animator.release())));
-}
+ // Animate linearly (the PaginationModel handles easing).
+ gfx::Rect bounds(
+ gfx::Tween::RectValueBetween(progress, from_rect, to_rect));
-ContentsAnimator* ContentsView::GetAnimatorForTransition(int from_page,
- int to_page,
- bool* reverse) const {
- auto it = contents_animators_.find(std::make_pair(from_page, to_page));
- if (it != contents_animators_.end()) {
- *reverse = false;
- return it->second.get();
+ page->SetBoundsRect(bounds);
}
- it = contents_animators_.find(std::make_pair(to_page, from_page));
- if (it != contents_animators_.end()) {
- *reverse = true;
- return it->second.get();
+ // Update the search box.
+ UpdateSearchBox(progress, current_state, target_state);
+}
+
+void ContentsView::UpdateSearchBox(double progress,
+ AppListModel::State current_state,
+ AppListModel::State target_state) {
+ AppListPage* from_page = GetPageView(GetPageIndexForState(current_state));
+ AppListPage* to_page = GetPageView(GetPageIndexForState(target_state));
+
+ SearchBoxView* search_box = GetSearchBoxView();
+
+ gfx::Rect search_box_from(from_page->GetSearchBoxBounds());
+ gfx::Rect search_box_to(to_page->GetSearchBoxBounds());
+ gfx::Rect search_box_rect =
+ gfx::Tween::RectValueBetween(progress, search_box_from, search_box_to);
+
+ int original_z_height = from_page->GetSearchBoxZHeight();
+ int target_z_height = to_page->GetSearchBoxZHeight();
+
+ if (original_z_height != target_z_height) {
+ gfx::ShadowValue original_shadow = GetShadowForZHeight(original_z_height);
+ gfx::ShadowValue target_shadow = GetShadowForZHeight(target_z_height);
+
+ gfx::Vector2d offset(gfx::Tween::LinearIntValueBetween(
+ progress, original_shadow.x(), target_shadow.x()),
+ gfx::Tween::LinearIntValueBetween(
+ progress, original_shadow.y(), target_shadow.y()));
+ search_box->SetShadow(gfx::ShadowValue(
+ offset, gfx::Tween::LinearIntValueBetween(
+ progress, original_shadow.blur(), target_shadow.blur()),
+ gfx::Tween::ColorValueBetween(progress, original_shadow.color(),
+ target_shadow.color())));
}
+ search_box->GetWidget()->SetBounds(
+ search_box->GetViewBoundsForSearchBoxContentsBounds(
+ ConvertRectToWidget(search_box_rect)));
+}
- *reverse = false;
- return default_animator_.get();
+PaginationModel* ContentsView::GetAppsPaginationModel() {
+ return apps_container_view_->apps_grid_view()->pagination_model();
}
void ContentsView::ShowFolderContent(AppListFolderItem* item) {
@@ -327,22 +335,23 @@ void ContentsView::Prerender() {
apps_container_view_->apps_grid_view()->Prerender();
}
-views::View* ContentsView::GetPageView(int index) const {
- return view_model_->view_at(index);
+AppListPage* ContentsView::GetPageView(int index) const {
+ DCHECK_GT(static_cast<int>(app_list_pages_.size()), index);
+ return app_list_pages_[index];
}
SearchBoxView* ContentsView::GetSearchBoxView() const {
return app_list_main_view_->search_box_view();
}
-int ContentsView::AddLauncherPage(views::View* view) {
- int page_index = view_model_->view_size();
+int ContentsView::AddLauncherPage(AppListPage* view) {
+ view->set_contents_view(this);
AddChildView(view);
- view_model_->Add(view, page_index);
- return page_index;
+ app_list_pages_.push_back(view);
+ return app_list_pages_.size() - 1;
}
-int ContentsView::AddLauncherPage(views::View* view,
+int ContentsView::AddLauncherPage(AppListPage* view,
AppListModel::State state) {
int page_index = AddLauncherPage(view);
bool success =
@@ -355,26 +364,6 @@ int ContentsView::AddLauncherPage(views::View* view,
return page_index;
}
-gfx::Rect ContentsView::GetOnscreenPageBounds(int page_index) const {
- AppListModel::State state = GetStateForPageIndex(page_index);
- bool fills_contents_view =
- state == AppListModel::STATE_CUSTOM_LAUNCHER_PAGE ||
- state == AppListModel::STATE_START;
- return fills_contents_view ? GetContentsBounds() : GetDefaultContentsBounds();
-}
-
-gfx::Rect ContentsView::GetOffscreenPageBounds(int page_index) const {
- AppListModel::State state = GetStateForPageIndex(page_index);
- gfx::Rect bounds(GetOnscreenPageBounds(page_index));
- // The start page and search page origins are above; all other pages' origins
- // are below.
- bool origin_above = state == AppListModel::STATE_START ||
- state == AppListModel::STATE_SEARCH_RESULTS;
- bounds.set_y(origin_above ? -bounds.height()
- : GetContentsBounds().height() + bounds.y());
- return bounds;
-}
-
gfx::Rect ContentsView::GetDefaultSearchBoxBounds() const {
gfx::Rect search_box_bounds(0, 0, GetDefaultContentsSize().width(),
GetSearchBoxView()->GetPreferredSize().height());
@@ -387,21 +376,8 @@ gfx::Rect ContentsView::GetDefaultSearchBoxBounds() const {
gfx::Rect ContentsView::GetSearchBoxBoundsForState(
AppListModel::State state) const {
- // On the start page, the search box is in a different location.
- if (state == AppListModel::STATE_START) {
- DCHECK(start_page_view_);
- // Convert to ContentsView space, assuming that the StartPageView is in the
- // ContentsView's default bounds.
- return start_page_view_->GetSearchBoxBounds() +
- GetOnscreenPageBounds(GetPageIndexForState(state))
- .OffsetFromOrigin();
- }
-
- return GetDefaultSearchBoxBounds();
-}
-
-gfx::Rect ContentsView::GetSearchBoxBoundsForPageIndex(int index) const {
- return GetSearchBoxBoundsForState(GetStateForPageIndex(index));
+ AppListPage* page = GetPageView(GetPageIndexForState(state));
+ return page->GetSearchBoxBounds();
}
gfx::Rect ContentsView::GetDefaultContentsBounds() const {
@@ -410,13 +386,6 @@ gfx::Rect ContentsView::GetDefaultContentsBounds() const {
return bounds;
}
-gfx::Rect ContentsView::GetCustomPageCollapsedBounds() const {
- gfx::Rect bounds(GetContentsBounds());
- int page_height = bounds.height();
- bounds.set_y(page_height - kCustomPageCollapsedHeight);
- return bounds;
-}
-
bool ContentsView::Back() {
AppListModel::State state = view_to_state_[GetActivePageIndex()];
switch (state) {
@@ -464,10 +433,6 @@ void ContentsView::Layout() {
// 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 = GetOnscreenPageBounds(GetActivePageIndex());
double progress =
IsStateActive(AppListModel::STATE_CUSTOM_LAUNCHER_PAGE) ? 1 : 0;
@@ -475,25 +440,11 @@ void ContentsView::Layout() {
app_list_main_view_->view_delegate()->CustomLauncherPageAnimationChanged(
progress);
- if (rect.IsEmpty())
+ if (GetContentsBounds().IsEmpty())
return;
- gfx::Rect offscreen_target(rect);
- offscreen_target.set_x(-rect.width());
-
- int current_page = GetActivePageIndex();
-
- for (int i = 0; i < view_model_->view_size(); ++i) {
- view_model_->view_at(i)
- ->SetBoundsRect(i == current_page ? rect : offscreen_target);
- }
-
- // Custom locations of pages in certain states.
- // Within the start page, the custom page is given its collapsed bounds.
- int start_page_index = GetPageIndexForState(AppListModel::STATE_START);
- if (current_page == start_page_index) {
- if (custom_page_view_)
- custom_page_view_->SetBoundsRect(GetCustomPageCollapsedBounds());
+ for (AppListPage* page : app_list_pages_) {
+ page->SetBoundsRect(page->GetPageBoundsForState(GetActiveState()));
}
// The search box is contained in a widget so set the bounds of the widget
@@ -509,8 +460,7 @@ void ContentsView::Layout() {
}
bool ContentsView::OnKeyPressed(const ui::KeyEvent& event) {
- bool handled =
- view_model_->view_at(GetActivePageIndex())->OnKeyPressed(event);
+ bool handled = app_list_pages_[GetActivePageIndex()]->OnKeyPressed(event);
if (!handled) {
if (event.key_code() == ui::VKEY_TAB && event.IsShiftDown()) {
@@ -526,19 +476,11 @@ void ContentsView::TotalPagesChanged() {
}
void ContentsView::SelectedPageChanged(int old_selected, int new_selected) {
- // TODO(mgiuca): This should be generalized so we call a virtual OnShow and
- // OnHide method for each page.
- if (!start_page_view_)
- return;
+ if (old_selected >= 0)
+ app_list_pages_[old_selected]->OnHidden();
- if (new_selected == GetPageIndexForState(AppListModel::STATE_START)) {
- start_page_view_->OnShow();
- // Show or hide the custom page view, based on whether it is enabled.
- if (custom_page_view_) {
- custom_page_view_->SetVisible(
- app_list_main_view_->ShouldShowCustomLauncherPage());
- }
- }
+ if (new_selected >= 0)
+ app_list_pages_[new_selected]->OnShown();
}
void ContentsView::TransitionStarted() {
diff --git a/ui/app_list/views/contents_view.h b/ui/app_list/views/contents_view.h
index e568b35..14c462e 100644
--- a/ui/app_list/views/contents_view.h
+++ b/ui/app_list/views/contents_view.h
@@ -26,11 +26,13 @@ class Rect;
namespace app_list {
class AppsGridView;
+class AppListPage;
class ApplicationDragAndDropHost;
class AppListFolderItem;
class AppListMainView;
class AppListViewDelegate;
class AppsContainerView;
+class CustomLauncherPageView;
class ContentsAnimator;
class PaginationModel;
class SearchBoxView;
@@ -98,11 +100,11 @@ class APP_LIST_EXPORT ContentsView : public views::View,
return apps_container_view_;
}
StartPageView* start_page_view() const { return start_page_view_; }
- views::View* custom_page_view() const { return custom_page_view_; }
+ CustomLauncherPageView* custom_page_view() const { return custom_page_view_; }
SearchResultPageView* search_results_page_view() {
return search_results_page_view_;
}
- views::View* GetPageView(int index) const;
+ AppListPage* GetPageView(int index) const;
SearchBoxView* GetSearchBoxView() const;
@@ -111,14 +113,6 @@ class APP_LIST_EXPORT ContentsView : public views::View,
// Returns the pagination model for the ContentsView.
const PaginationModel& pagination_model() { return pagination_model_; }
- // Gets the on-screen page bounds for a given launcher page with index
- // |page_index|.
- gfx::Rect GetOnscreenPageBounds(int page_index) const;
-
- // Gets the the off-screen resting place for a given launcher page with index
- // |page_index|.
- gfx::Rect GetOffscreenPageBounds(int page_index) const;
-
// Returns search box bounds to use for content views that do not specify
// their own custom layout.
gfx::Rect GetDefaultSearchBoxBounds() const;
@@ -126,25 +120,10 @@ class APP_LIST_EXPORT ContentsView : public views::View,
// Returns search box bounds to use for a given state.
gfx::Rect GetSearchBoxBoundsForState(AppListModel::State state) const;
- // Returns search box bounds to use for a given page index.
- gfx::Rect GetSearchBoxBoundsForPageIndex(int index) const;
-
// Returns the content area bounds to use for content views that do not
// specify their own custom layout.
gfx::Rect GetDefaultContentsBounds() const;
- // Gets the location of the custom launcher page in "collapsed" state. This is
- // where the page is peeking in from the bottom of the launcher (neither full
- // on-screen or off-screen).
- gfx::Rect GetCustomPageCollapsedBounds() const;
-
- // Exposes GetAnimatorForTransition for tests.
- ContentsAnimator* GetAnimatorForTransitionForTests(int from_page,
- int to_page,
- bool* reverse) const {
- return GetAnimatorForTransition(from_page, to_page, reverse);
- }
-
// Performs the 'back' action for the active page. Returns whether the action
// was handled.
bool Back();
@@ -183,46 +162,38 @@ class APP_LIST_EXPORT ContentsView : public views::View,
// animation, this positions the views as appropriate for the current frame.
void UpdatePageBounds();
+ void UpdateSearchBox(double progress,
+ AppListModel::State current_state,
+ AppListModel::State target_state);
+
// Adds |view| as a new page to the end of the list of launcher pages. The
// view is inserted as a child of the ContentsView. There is no name
// associated with the page. Returns the index of the new page.
- int AddLauncherPage(views::View* view);
+ int AddLauncherPage(AppListPage* view);
// Adds |view| as a new page to the end of the list of launcher pages. The
// view is inserted as a child of the ContentsView. The page is associated
// with the name |state|. Returns the index of the new page.
- int AddLauncherPage(views::View* view, AppListModel::State state);
+ int AddLauncherPage(AppListPage* view, AppListModel::State state);
// Gets the PaginationModel owned by the AppsGridView.
// Note: This is different to |pagination_model_|, which manages top-level
// launcher-page pagination.
PaginationModel* GetAppsPaginationModel();
- // Adds a ContentsAnimator for a transition from |from_state| to |to_state|.
- void AddAnimator(AppListModel::State from_state,
- AppListModel::State to_state,
- scoped_ptr<ContentsAnimator> animator);
-
- // Gets a ContentsAnimator for a transition from |from_page| to |to_page|. If
- // the animator should be run in reverse (because it is a |to_page| to
- // |from_page| animator), |reverse| is set to true; otherwise it is set to
- // false.
- ContentsAnimator* GetAnimatorForTransition(int from_page,
- int to_page,
- bool* reverse) const;
-
// Special sub views of the ContentsView. All owned by the views hierarchy.
AppsContainerView* apps_container_view_;
-
SearchResultPageView* search_results_page_view_;
// Only used in the experimental app list.
StartPageView* start_page_view_;
- views::View* custom_page_view_;
+ CustomLauncherPageView* custom_page_view_;
- AppListMainView* app_list_main_view_; // Parent view, owns this.
+ // The child page views. Owned by the views hierarchy.
+ std::vector<AppListPage*> app_list_pages_;
- scoped_ptr<views::ViewModel> view_model_;
+ // Parent view. Owned by the views hierarchy.
+ AppListMainView* app_list_main_view_;
// Maps State onto |view_model_| indices.
std::map<AppListModel::State, int> state_to_view_;
@@ -236,14 +207,6 @@ class APP_LIST_EXPORT ContentsView : public views::View,
// Manages the pagination for the launcher pages.
PaginationModel pagination_model_;
- // Maps from {A, B} pair to ContentsAnimator, where A and B are page
- // |view_model_| indices for an animation from A to B.
- std::map<std::pair<int, int>, linked_ptr<ContentsAnimator>>
- contents_animators_;
-
- // The animator for transitions not found in |contents_animators_|.
- scoped_ptr<ContentsAnimator> default_animator_;
-
DISALLOW_COPY_AND_ASSIGN(ContentsView);
};
diff --git a/ui/app_list/views/contents_view_unittest.cc b/ui/app_list/views/contents_view_unittest.cc
deleted file mode 100644
index a7d9fb7..0000000
--- a/ui/app_list/views/contents_view_unittest.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/app_list/views/contents_view.h"
-
-#include "base/command_line.h"
-#include "base/memory/scoped_ptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/app_list/app_list_switches.h"
-#include "ui/app_list/test/app_list_test_model.h"
-#include "ui/app_list/test/app_list_test_view_delegate.h"
-#include "ui/app_list/views/app_list_main_view.h"
-#include "ui/app_list/views/contents_animator.h"
-#include "ui/app_list/views/search_box_view.h"
-
-namespace app_list {
-namespace test {
-
-class ContentsViewTest : public testing::Test {
- public:
- ContentsViewTest() {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableExperimentalAppList);
-
- delegate_.reset(new AppListTestViewDelegate());
- main_view_.reset(new app_list::AppListMainView(delegate_.get()));
- search_box_view_.reset(
- new SearchBoxView(main_view_.get(), delegate_.get()));
-
- main_view_->Init(NULL, 0, search_box_view_.get());
- DCHECK(GetContentsView());
- }
-
- ~ContentsViewTest() override {}
-
- protected:
- ContentsView* GetContentsView() const { return main_view_->contents_view(); }
-
- private:
- scoped_ptr<AppListTestViewDelegate> delegate_;
- scoped_ptr<AppListMainView> main_view_;
- scoped_ptr<SearchBoxView> search_box_view_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentsViewTest);
-};
-
-TEST_F(ContentsViewTest, CustomAnimationsTest) {
- ContentsView* contents_view = GetContentsView();
- ContentsAnimator* animator;
- bool reverse = true; // Set to true to make sure it is written.
-
- // A transition without a custom animation.
- animator = contents_view->GetAnimatorForTransitionForTests(
- contents_view->GetPageIndexForState(AppListModel::STATE_START),
- contents_view->GetPageIndexForState(AppListModel::STATE_SEARCH_RESULTS),
- &reverse);
- EXPECT_EQ("DefaultAnimator", animator->NameForTests());
- EXPECT_FALSE(reverse);
-
- // Test some custom animations.
- reverse = true;
- animator = contents_view->GetAnimatorForTransitionForTests(
- contents_view->GetPageIndexForState(AppListModel::STATE_START),
- contents_view->GetPageIndexForState(AppListModel::STATE_APPS), &reverse);
- EXPECT_EQ("StartToAppsAnimator", animator->NameForTests());
- EXPECT_FALSE(reverse);
-
- reverse = false;
- animator = contents_view->GetAnimatorForTransitionForTests(
- contents_view->GetPageIndexForState(AppListModel::STATE_APPS),
- contents_view->GetPageIndexForState(AppListModel::STATE_START), &reverse);
- EXPECT_EQ("StartToAppsAnimator", animator->NameForTests());
- EXPECT_TRUE(reverse);
-}
-
-} // namespace test
-} // namespace app_list
diff --git a/ui/app_list/views/custom_launcher_page_view.cc b/ui/app_list/views/custom_launcher_page_view.cc
new file mode 100644
index 0000000..c6934ef
--- /dev/null
+++ b/ui/app_list/views/custom_launcher_page_view.cc
@@ -0,0 +1,50 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/app_list/views/custom_launcher_page_view.h"
+
+#include "ui/app_list/app_list_constants.h"
+#include "ui/views/layout/fill_layout.h"
+
+namespace app_list {
+
+CustomLauncherPageView::CustomLauncherPageView(
+ View* custom_launcher_page_contents)
+ : custom_launcher_page_contents_(custom_launcher_page_contents) {
+ SetLayoutManager(new views::FillLayout());
+ AddChildView(custom_launcher_page_contents_);
+}
+
+CustomLauncherPageView::~CustomLauncherPageView() {
+}
+
+gfx::Rect CustomLauncherPageView::GetCollapsedLauncherPageBounds() const {
+ gfx::Rect rect = GetFullContentsBounds();
+ int page_height = rect.height();
+ rect.set_y(page_height - kCustomPageCollapsedHeight);
+ return rect;
+}
+
+gfx::Rect CustomLauncherPageView::GetPageBoundsForState(
+ AppListModel::State state) const {
+ gfx::Rect onscreen_bounds = GetFullContentsBounds();
+ switch (state) {
+ case AppListModel::STATE_CUSTOM_LAUNCHER_PAGE:
+ return onscreen_bounds;
+ case AppListModel::STATE_START:
+ return GetCollapsedLauncherPageBounds();
+ default:
+ return GetBelowContentsOffscreenBounds(onscreen_bounds.size());
+ }
+}
+
+void CustomLauncherPageView::OnShown() {
+ custom_launcher_page_contents_->SetFocusable(true);
+}
+
+void CustomLauncherPageView::OnWillBeHidden() {
+ custom_launcher_page_contents_->SetFocusable(false);
+}
+
+} // namespace app_list
diff --git a/ui/app_list/views/custom_launcher_page_view.h b/ui/app_list/views/custom_launcher_page_view.h
new file mode 100644
index 0000000..0c5708c
--- /dev/null
+++ b/ui/app_list/views/custom_launcher_page_view.h
@@ -0,0 +1,41 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_APP_LIST_VIEWS_CUSTOM_LAUNCHER_PAGE_VIEW_H_
+#define UI_APP_LIST_VIEWS_CUSTOM_LAUNCHER_PAGE_VIEW_H_
+
+#include "ui/app_list/app_list_export.h"
+#include "ui/app_list/views/app_list_page.h"
+
+namespace app_list {
+
+// A wrapper view around the custom launcher page web view.
+class APP_LIST_EXPORT CustomLauncherPageView : public AppListPage {
+ public:
+ explicit CustomLauncherPageView(View* custom_launcher_page_webview);
+ ~CustomLauncherPageView() override;
+
+ // Gets the location of the custom launcher page in "collapsed" state. This is
+ // where the page is peeking in from the bottom of the launcher (neither full
+ // on-screen or off-screen).
+ gfx::Rect GetCollapsedLauncherPageBounds() const;
+
+ View* custom_launcher_page_contents() {
+ return custom_launcher_page_contents_;
+ }
+
+ // AppListPage overrides:
+ gfx::Rect GetPageBoundsForState(AppListModel::State state) const override;
+ void OnShown() override;
+ void OnWillBeHidden() override;
+
+ private:
+ View* custom_launcher_page_contents_;
+
+ DISALLOW_COPY_AND_ASSIGN(CustomLauncherPageView);
+};
+
+} // namespace app_list
+
+#endif // UI_APP_LIST_VIEWS_CUSTOM_LAUNCHER_PAGE_VIEW_H_
diff --git a/ui/app_list/views/search_result_page_view.cc b/ui/app_list/views/search_result_page_view.cc
index 2af6d58..c3ff198 100644
--- a/ui/app_list/views/search_result_page_view.cc
+++ b/ui/app_list/views/search_result_page_view.cc
@@ -26,12 +26,16 @@ namespace {
const int kGroupSpacing = 6;
const int kTopPadding = 8;
+// The z-height of the search box and cards in this view.
+const int kSearchResultZHeight = 1;
+
// A container view that ensures the card background and the shadow are painted
// in the correct order.
class SearchCardView : public views::View {
public:
explicit SearchCardView(views::View* content_view) {
- SetBorder(make_scoped_ptr(new views::ShadowBorder(GetShadowForZHeight(1))));
+ SetBorder(make_scoped_ptr(
+ new views::ShadowBorder(GetShadowForZHeight(kSearchResultZHeight))));
SetLayoutManager(new views::FillLayout());
content_view->set_background(
views::Background::CreateSolidBackground(kCardBackgroundColor));
@@ -50,7 +54,7 @@ class SearchCardView : public views::View {
SearchResultPageView::SearchResultPageView() : selected_index_(0) {
if (switches::IsExperimentalAppListEnabled()) {
- gfx::ShadowValue shadow = GetShadowForZHeight(1);
+ gfx::ShadowValue shadow = GetShadowForZHeight(kSearchResultZHeight);
scoped_ptr<views::Border> border(new views::ShadowBorder(shadow));
gfx::Insets insets = gfx::Insets(kTopPadding, kExperimentalSearchBoxPadding,
@@ -163,4 +167,32 @@ void SearchResultPageView::ChildPreferredSizeChanged(views::View* child) {
SetSelectedIndex(0, false);
}
+gfx::Rect SearchResultPageView::GetPageBoundsForState(
+ AppListModel::State state) const {
+ gfx::Rect onscreen_bounds = GetDefaultContentsBounds();
+ switch (state) {
+ case AppListModel::STATE_SEARCH_RESULTS:
+ return onscreen_bounds;
+ default:
+ return GetAboveContentsOffscreenBounds(onscreen_bounds.size());
+ }
+}
+
+void SearchResultPageView::OnAnimationUpdated(double progress,
+ AppListModel::State from_state,
+ AppListModel::State to_state) {
+ if (from_state != AppListModel::STATE_SEARCH_RESULTS &&
+ to_state != AppListModel::STATE_SEARCH_RESULTS) {
+ return;
+ }
+
+ gfx::Rect onscreen_bounds(
+ GetPageBoundsForState(AppListModel::STATE_SEARCH_RESULTS));
+ set_clip_insets(bounds().InsetsFrom(onscreen_bounds));
+}
+
+int SearchResultPageView::GetSearchBoxZHeight() const {
+ return kSearchResultZHeight;
+}
+
} // namespace app_list
diff --git a/ui/app_list/views/search_result_page_view.h b/ui/app_list/views/search_result_page_view.h
index d01c0a4..31d8dd8 100644
--- a/ui/app_list/views/search_result_page_view.h
+++ b/ui/app_list/views/search_result_page_view.h
@@ -11,7 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "ui/app_list/app_list_export.h"
#include "ui/app_list/app_list_model.h"
-#include "ui/views/view.h"
+#include "ui/app_list/views/app_list_page.h"
namespace app_list {
@@ -20,7 +20,7 @@ class AppListViewDelegate;
class SearchResultContainerView;
// The start page for the experimental app list.
-class APP_LIST_EXPORT SearchResultPageView : public views::View {
+class APP_LIST_EXPORT SearchResultPageView : public AppListPage {
public:
SearchResultPageView();
~SearchResultPageView() override;
@@ -40,6 +40,13 @@ class APP_LIST_EXPORT SearchResultPageView : public views::View {
bool OnKeyPressed(const ui::KeyEvent& event) override;
void ChildPreferredSizeChanged(views::View* child) override;
+ // AppListPage overrides:
+ gfx::Rect GetPageBoundsForState(AppListModel::State state) const override;
+ void OnAnimationUpdated(double progress,
+ AppListModel::State from_state,
+ AppListModel::State to_state) override;
+ int GetSearchBoxZHeight() const override;
+
private:
// |directional_movement| is true if the navigation was caused by directional
// controls (eg, arrow keys), as opposed to linear controls (eg, Tab).
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc
index 1c62aca..343fcad 100644
--- a/ui/app_list/views/start_page_view.cc
+++ b/ui/app_list/views/start_page_view.cc
@@ -18,6 +18,7 @@
#include "ui/app_list/views/all_apps_tile_item_view.h"
#include "ui/app_list/views/app_list_main_view.h"
#include "ui/app_list/views/contents_view.h"
+#include "ui/app_list/views/custom_launcher_page_view.h"
#include "ui/app_list/views/search_box_view.h"
#include "ui/app_list/views/search_result_container_view.h"
#include "ui/app_list/views/search_result_tile_item_view.h"
@@ -299,12 +300,34 @@ TileItemView* StartPageView::all_apps_button() const {
return tiles_container_->all_apps_button();
}
-void StartPageView::OnShow() {
+void StartPageView::OnShown() {
+ // When the start page is shown, show or hide the custom launcher page
+ // based on whether it is enabled.
+ CustomLauncherPageView* custom_page_view =
+ app_list_main_view_->contents_view()->custom_page_view();
+ if (custom_page_view) {
+ custom_page_view->SetVisible(
+ app_list_main_view_->ShouldShowCustomLauncherPage());
+ }
tiles_container_->Update();
tiles_container_->ClearSelectedIndex();
custom_launcher_page_background_->SetSelected(false);
}
+gfx::Rect StartPageView::GetPageBoundsForState(
+ AppListModel::State state) const {
+ gfx::Rect onscreen_bounds(GetFullContentsBounds());
+ if (state == AppListModel::STATE_START)
+ return onscreen_bounds;
+
+ return GetAboveContentsOffscreenBounds(onscreen_bounds.size());
+}
+
+gfx::Rect StartPageView::GetSearchBoxBounds() const {
+ return search_box_spacer_view_->bounds() +
+ GetPageBoundsForState(AppListModel::STATE_START).OffsetFromOrigin();
+}
+
void StartPageView::Layout() {
gfx::Rect bounds(GetContentsBounds());
bounds.set_height(instant_container_->GetHeightForWidth(bounds.width()));
@@ -315,7 +338,14 @@ void StartPageView::Layout() {
bounds.set_height(tiles_container_->GetHeightForWidth(bounds.width()));
tiles_container_->SetBoundsRect(bounds);
- bounds = app_list_main_view_->contents_view()->GetCustomPageCollapsedBounds();
+ CustomLauncherPageView* custom_launcher_page_view =
+ app_list_main_view_->contents_view()->custom_page_view();
+ if (!custom_launcher_page_view)
+ return;
+
+ bounds = app_list_main_view_->contents_view()
+ ->custom_page_view()
+ ->GetCollapsedLauncherPageBounds();
bounds.Intersect(GetContentsBounds());
bounds.ClampToCenteredSize(
gfx::Size(kLauncherPageBackgroundWidth, bounds.height()));
@@ -404,8 +434,12 @@ bool StartPageView::OnKeyPressed(const ui::KeyEvent& event) {
bool StartPageView::OnMousePressed(const ui::MouseEvent& event) {
ContentsView* contents_view = app_list_main_view_->contents_view();
- if (!contents_view->GetCustomPageCollapsedBounds().Contains(event.location()))
+ if (contents_view->custom_page_view() &&
+ !contents_view->custom_page_view()
+ ->GetCollapsedLauncherPageBounds()
+ .Contains(event.location())) {
return false;
+ }
MaybeOpenCustomLauncherPage();
return true;
@@ -423,13 +457,18 @@ bool StartPageView::OnMouseWheel(const ui::MouseWheelEvent& event) {
void StartPageView::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN &&
- event->details().scroll_y_hint() < 0)
+ event->details().scroll_y_hint() < 0) {
MaybeOpenCustomLauncherPage();
+ }
ContentsView* contents_view = app_list_main_view_->contents_view();
if (event->type() == ui::ET_GESTURE_TAP &&
- contents_view->GetCustomPageCollapsedBounds().Contains(event->location()))
+ contents_view->custom_page_view() &&
+ contents_view->custom_page_view()
+ ->GetCollapsedLauncherPageBounds()
+ .Contains(event->location())) {
MaybeOpenCustomLauncherPage();
+ }
}
void StartPageView::OnScrollEvent(ui::ScrollEvent* event) {
@@ -439,10 +478,6 @@ void StartPageView::OnScrollEvent(ui::ScrollEvent* event) {
MaybeOpenCustomLauncherPage();
}
-gfx::Rect StartPageView::GetSearchBoxBounds() const {
- return search_box_spacer_view_->bounds();
-}
-
TileItemView* StartPageView::GetTileItemView(size_t index) {
return tiles_container_->GetTileItemView(index);
}
diff --git a/ui/app_list/views/start_page_view.h b/ui/app_list/views/start_page_view.h
index fa97e80..ca5c59a 100644
--- a/ui/app_list/views/start_page_view.h
+++ b/ui/app_list/views/start_page_view.h
@@ -9,7 +9,7 @@
#include "base/basictypes.h"
#include "ui/app_list/app_list_export.h"
-#include "ui/views/view.h"
+#include "ui/app_list/views/app_list_page.h"
namespace app_list {
@@ -21,7 +21,7 @@ class SearchResultTileItemView;
class TileItemView;
// The start page for the experimental app list.
-class APP_LIST_EXPORT StartPageView : public views::View {
+class APP_LIST_EXPORT StartPageView : public AppListPage {
public:
StartPageView(AppListMainView* app_list_main_view,
AppListViewDelegate* view_delegate);
@@ -35,8 +35,10 @@ class APP_LIST_EXPORT StartPageView : public views::View {
const std::vector<SearchResultTileItemView*>& tile_views() const;
TileItemView* all_apps_button() const;
- // Called when the start page view is displayed.
- void OnShow();
+ // Overridden from AppListPage:
+ gfx::Rect GetPageBoundsForState(AppListModel::State state) const override;
+ gfx::Rect GetSearchBoxBounds() const override;
+ void OnShown() override;
// Overridden from views::View:
void Layout() override;
@@ -47,8 +49,6 @@ class APP_LIST_EXPORT StartPageView : public views::View {
void OnGestureEvent(ui::GestureEvent* event) override;
void OnScrollEvent(ui::ScrollEvent* event) override;
- // Returns search box bounds to use when the start page is active.
- gfx::Rect GetSearchBoxBounds() const;
private:
class StartPageTilesContainer;