summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormukai <mukai@chromium.org>2014-08-26 11:35:58 -0700
committerCommit bot <commit-bot@chromium.org>2014-08-26 18:45:26 +0000
commitc96ea8f3e111c9fc6c0f0b12f893e84289f40510 (patch)
tree9de21f5dce86e8c956eaf3cc8d527e2f40e1d50a
parent364fed76f11a1e81e89b7de0686723ec6ad8736d (diff)
downloadchromium_src-c96ea8f3e111c9fc6c0f0b12f893e84289f40510.zip
chromium_src-c96ea8f3e111c9fc6c0f0b12f893e84289f40510.tar.gz
chromium_src-c96ea8f3e111c9fc6c0f0b12f893e84289f40510.tar.bz2
Exports gesture manager to a separate file and adds its unittests.
BUG=403813 R=sadrul@chromium.org TEST=athena_unittests Review URL: https://codereview.chromium.org/502583002 Cr-Commit-Position: refs/heads/master@{#291945}
-rw-r--r--athena/athena.gyp5
-rw-r--r--athena/home/DEPS1
-rw-r--r--athena/home/athena_start_page_view.cc10
-rw-r--r--athena/home/home_card_constants.cc12
-rw-r--r--athena/home/home_card_constants.h20
-rw-r--r--athena/home/home_card_gesture_manager.cc115
-rw-r--r--athena/home/home_card_gesture_manager.h71
-rw-r--r--athena/home/home_card_gesture_manager_unittest.cc171
-rw-r--r--athena/home/home_card_impl.cc149
9 files changed, 401 insertions, 153 deletions
diff --git a/athena/athena.gyp b/athena/athena.gyp
index 713c1d3..99e8079 100644
--- a/athena/athena.gyp
+++ b/athena/athena.gyp
@@ -55,6 +55,10 @@
'home/app_list_view_delegate.h',
'home/athena_start_page_view.cc',
'home/athena_start_page_view.h',
+ 'home/home_card_constants.cc',
+ 'home/home_card_constants.h',
+ 'home/home_card_gesture_manager.cc',
+ 'home/home_card_gesture_manager.h',
'home/home_card_impl.cc',
'home/minimized_home.cc',
'home/minimized_home.h',
@@ -206,6 +210,7 @@
'activity/activity_manager_unittest.cc',
'common/fill_layout_manager_unittest.cc',
'content/app_activity_unittest.cc',
+ 'home/home_card_gesture_manager_unittest.cc',
'home/home_card_unittest.cc',
'input/accelerator_manager_unittest.cc',
'screen/screen_manager_unittest.cc',
diff --git a/athena/home/DEPS b/athena/home/DEPS
index 768b162..e6ce933 100644
--- a/athena/home/DEPS
+++ b/athena/home/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+athena/athena_export.h",
"+athena/env/public",
"+athena/input/public",
"+athena/screen/public",
diff --git a/athena/home/athena_start_page_view.cc b/athena/home/athena_start_page_view.cc
index 3bbcd44..b5b8fb9 100644
--- a/athena/home/athena_start_page_view.cc
+++ b/athena/home/athena_start_page_view.cc
@@ -4,6 +4,7 @@
#include "athena/home/athena_start_page_view.h"
+#include "athena/home/home_card_constants.h"
#include "base/bind.h"
#include "base/strings/string_util.h"
#include "third_party/skia/include/core/SkPaint.h"
@@ -42,9 +43,6 @@ const int kSearchBoxCornerRadius = 2;
const int kSearchBoxWidth = 490;
const int kSearchBoxHeight = 40;
-// The preferred height for VISIBLE_BOTTOM state.
-const int kPreferredHeightBottom = 100;
-
class PlaceHolderButton : public views::ImageButton,
public views::ButtonListener {
public:
@@ -214,7 +212,7 @@ void AthenaStartPageView::LayoutSearchResults(bool should_show_search_results) {
search_results_view_->layer()->GetTargetVisibility()) {
return;
}
- if (GetContentsBounds().height() <= kPreferredHeightBottom) {
+ if (GetContentsBounds().height() <= kHomeCardHeight) {
search_results_view_->SetVisible(false);
Layout();
return;
@@ -281,7 +279,7 @@ void AthenaStartPageView::Layout() {
gfx::Rect bounds = GetContentsBounds();
search_results_view_->SetVisible(false);
- if (bounds.height() <= kPreferredHeightBottom) {
+ if (bounds.height() <= kHomeCardHeight) {
logo_->SetVisible(false);
gfx::Rect icon_bounds(app_icon_container_->GetPreferredSize());
icon_bounds.set_x(bounds.x() + kIconMargin);
@@ -296,7 +294,7 @@ void AthenaStartPageView::Layout() {
search_box_container_->SetBounds(
icon_bounds.right(), bounds.y(),
- control_bounds.x() - icon_bounds.right(), kPreferredHeightBottom);
+ control_bounds.x() - icon_bounds.right(), kHomeCardHeight);
set_background(views::Background::CreateSolidBackground(
255, 255, 255, 255 * 0.9));
diff --git a/athena/home/home_card_constants.cc b/athena/home/home_card_constants.cc
new file mode 100644
index 0000000..38596c4
--- /dev/null
+++ b/athena/home/home_card_constants.cc
@@ -0,0 +1,12 @@
+// 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 "athena/home/home_card_constants.h"
+
+namespace athena {
+
+const int kHomeCardHeight = 100;
+const int kHomeCardMinimizedHeight = 6;
+
+} // namespace athena
diff --git a/athena/home/home_card_constants.h b/athena/home/home_card_constants.h
new file mode 100644
index 0000000..57520ec
--- /dev/null
+++ b/athena/home/home_card_constants.h
@@ -0,0 +1,20 @@
+// 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 ATHENA_HOME_HOME_CARD_CONSTANTS_H_
+#define ATHENA_HOME_HOME_CARD_CONSTANTS_H_
+
+#include "athena/athena_export.h"
+
+namespace athena {
+
+// The height of the home card in BOTTOM state.
+ATHENA_EXPORT extern const int kHomeCardHeight;
+
+// The height of the home card of MINIMIZED state.
+ATHENA_EXPORT extern const int kHomeCardMinimizedHeight;
+
+} // namespace athena
+
+#endif // ATHENA_HOME_HOME_CARD_CONSTANTS_H_
diff --git a/athena/home/home_card_gesture_manager.cc b/athena/home/home_card_gesture_manager.cc
new file mode 100644
index 0000000..755c29c
--- /dev/null
+++ b/athena/home/home_card_gesture_manager.cc
@@ -0,0 +1,115 @@
+// 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 "athena/home/home_card_gesture_manager.h"
+
+#include "athena/home/home_card_constants.h"
+#include "ui/events/event.h"
+
+namespace athena {
+
+HomeCardGestureManager::HomeCardGestureManager(Delegate* delegate,
+ const gfx::Rect& screen_bounds)
+ : delegate_(delegate),
+ last_state_(HomeCard::Get()->GetState()),
+ y_offset_(0),
+ last_estimated_height_(0),
+ screen_bounds_(screen_bounds) {}
+
+HomeCardGestureManager::~HomeCardGestureManager() {}
+
+void HomeCardGestureManager::ProcessGestureEvent(ui::GestureEvent* event) {
+ switch (event->type()) {
+ case ui::ET_GESTURE_SCROLL_BEGIN:
+ y_offset_ = event->location().y();
+ event->SetHandled();
+ break;
+ case ui::ET_GESTURE_SCROLL_END:
+ event->SetHandled();
+ delegate_->OnGestureEnded(GetClosestState());
+ break;
+ case ui::ET_GESTURE_SCROLL_UPDATE:
+ UpdateScrollState(*event);
+ break;
+ case ui::ET_SCROLL_FLING_START: {
+ const ui::GestureEventDetails& details = event->details();
+ const float kFlingCompletionVelocity = 100.0f;
+ if (::fabs(details.velocity_y()) > kFlingCompletionVelocity) {
+ int step = (details.velocity_y() > 0) ? 1 : -1;
+ int new_state = static_cast<int>(last_state_) + step;
+ if (new_state >= HomeCard::VISIBLE_CENTERED &&
+ new_state <= HomeCard::VISIBLE_MINIMIZED) {
+ last_state_ = static_cast<HomeCard::State>(new_state);
+ }
+ delegate_->OnGestureEnded(last_state_);
+ }
+ break;
+ }
+ default:
+ // do nothing.
+ break;
+ }
+}
+
+HomeCard::State HomeCardGestureManager::GetClosestState() const {
+ // The top position of the bounds for one smaller state than the current
+ // one.
+
+ if (last_estimated_height_ <= kHomeCardMinimizedHeight)
+ return HomeCard::VISIBLE_MINIMIZED;
+
+ HomeCard::State smaller_state = HomeCard::VISIBLE_MINIMIZED;
+ int smaller_height = kHomeCardMinimizedHeight;
+ int bigger_height = kHomeCardHeight;
+ if (last_estimated_height_ > kHomeCardHeight) {
+ smaller_state = HomeCard::VISIBLE_BOTTOM;
+ smaller_height = kHomeCardHeight;
+ bigger_height = screen_bounds_.height();
+ }
+
+ if (last_estimated_height_ - smaller_height <=
+ (bigger_height - smaller_height) / 5) {
+ return smaller_state;
+ }
+
+ return static_cast<HomeCard::State>(smaller_state - 1);
+}
+
+void HomeCardGestureManager::UpdateScrollState(const ui::GestureEvent& event) {
+ last_estimated_height_ =
+ screen_bounds_.height() - event.root_location().y() + y_offset_;
+
+ if (last_estimated_height_ <= kHomeCardMinimizedHeight) {
+ delegate_->OnGestureProgressed(
+ last_state_, HomeCard::VISIBLE_MINIMIZED, 1.0f);
+ last_state_ = HomeCard::VISIBLE_MINIMIZED;
+ return;
+ }
+
+ HomeCard::State state = HomeCard::VISIBLE_BOTTOM;
+ float smaller_height = kHomeCardMinimizedHeight;
+ float bigger_height = kHomeCardHeight;
+ if (last_estimated_height_ > kHomeCardHeight) {
+ state = HomeCard::VISIBLE_CENTERED;
+ smaller_height = kHomeCardHeight;
+ bigger_height = screen_bounds_.height();
+ }
+
+ // The finger is between two states.
+ float progress = (last_estimated_height_ - smaller_height) /
+ (bigger_height - smaller_height);
+
+ if (last_state_ == state) {
+ if (event.details().scroll_y() > 0) {
+ state = static_cast<HomeCard::State>(state + 1);
+ progress = 1.0f - progress;
+ } else {
+ last_state_ = static_cast<HomeCard::State>(last_state_ + 1);
+ }
+ }
+ delegate_->OnGestureProgressed(last_state_, state, progress);
+ last_state_ = state;
+}
+
+} // namespace athena
diff --git a/athena/home/home_card_gesture_manager.h b/athena/home/home_card_gesture_manager.h
new file mode 100644
index 0000000..8749b91
--- /dev/null
+++ b/athena/home/home_card_gesture_manager.h
@@ -0,0 +1,71 @@
+// 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 ATHENA_HOME_HOME_CARD_GESTURE_MANAGER_H_
+#define ATHENA_HOME_HOME_CARD_GESTURE_MANAGER_H_
+
+#include "athena/home/public/home_card.h"
+#include "athena/athena_export.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace ui {
+class GestureEvent;
+}
+
+namespace athena {
+
+// Handles the touch gestures over the home card.
+class ATHENA_EXPORT HomeCardGestureManager {
+ public:
+ class Delegate {
+ public:
+ // Called when the gesture has ended. The state of the home card will
+ // end up with |final_state|.
+ virtual void OnGestureEnded(HomeCard::State final_state) = 0;
+
+ // Called when the gesture position is updated so that |delegate| should
+ // update the visual. The arguments represent the state of the current
+ // gesture position is switching from |from_state| to |to_state|, and
+ // the level of the progress is at |progress|, which is 0 to 1.
+ // |from_state| and |to_state| could be same. For example, if the user moves
+ // the finger down to the bottom of the screen, both states are MINIMIZED.
+ // In that case |progress| is 0.
+ virtual void OnGestureProgressed(
+ HomeCard::State from_state,
+ HomeCard::State to_state,
+ float progress) = 0;
+ };
+
+ HomeCardGestureManager(Delegate* delegate,
+ const gfx::Rect& screen_bounds);
+ ~HomeCardGestureManager();
+
+ void ProcessGestureEvent(ui::GestureEvent* event);
+
+ private:
+ // Get the closest state from the last position.
+ HomeCard::State GetClosestState() const;
+
+ // Update the current position and emits OnGestureProgressed().
+ void UpdateScrollState(const ui::GestureEvent& event);
+
+ Delegate* delegate_; // Not owned.
+ HomeCard::State last_state_;
+
+ // The offset from the top edge of the home card and the initial position of
+ // gesture.
+ int y_offset_;
+
+ // The estimated height of the home card after the last touch event.
+ int last_estimated_height_;
+
+ // The bounds of the screen to compute the home card bounds.
+ gfx::Rect screen_bounds_;
+
+ DISALLOW_COPY_AND_ASSIGN(HomeCardGestureManager);
+};
+
+} // namespace athena
+
+#endif // ATHENA_HOME_HOME_CARD_GESTURE_MANAGER_H_
diff --git a/athena/home/home_card_gesture_manager_unittest.cc b/athena/home/home_card_gesture_manager_unittest.cc
new file mode 100644
index 0000000..06dc792
--- /dev/null
+++ b/athena/home/home_card_gesture_manager_unittest.cc
@@ -0,0 +1,171 @@
+// 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 "athena/home/home_card_gesture_manager.h"
+
+#include "athena/home/home_card_constants.h"
+#include "athena/home/public/home_card.h"
+#include "athena/test/athena_test_base.h"
+#include "base/time/time.h"
+#include "ui/events/event.h"
+#include "ui/events/event_constants.h"
+
+namespace athena {
+
+class HomeCardGestureManagerTest : public test::AthenaTestBase,
+ public HomeCardGestureManager::Delegate {
+ public:
+ HomeCardGestureManagerTest()
+ : final_state_(HomeCard::HIDDEN),
+ last_from_state_(HomeCard::HIDDEN),
+ last_to_state_(HomeCard::HIDDEN),
+ last_progress_(0.0f),
+ last_y_(0),
+ progress_count_(0),
+ end_count_(0) {}
+ virtual ~HomeCardGestureManagerTest() {}
+
+ // testing::Test:
+ virtual void SetUp() OVERRIDE {
+ test::AthenaTestBase::SetUp();
+ gesture_manager_.reset(new HomeCardGestureManager(this, screen_bounds()));
+ }
+
+ protected:
+ int GetEndCountAndReset() {
+ int result = end_count_;
+ end_count_ = 0;
+ return result;
+ }
+ int GetProgressCountAndReset() {
+ int result = progress_count_;
+ progress_count_ = 0;
+ return result;
+ }
+
+ // Process a gesture event for our use case.
+ bool ProcessGestureEvent(ui::EventType type, int y) {
+ ui::GestureEvent event(0, y, ui::EF_NONE, base::TimeDelta(),
+ ui::GestureEventDetails(type, 0, (y - last_y_)));
+ // Assumes the initial location is based on minimized height.
+ if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
+ gfx::Point location = event.location();
+ location.set_y(
+ location.y() - (screen_bounds().bottom() - kHomeCardMinimizedHeight));
+ event.set_location(location);
+ }
+ gesture_manager_->ProcessGestureEvent(&event);
+ last_y_ = y;
+ return event.handled();
+ }
+ void ProcessFlingGesture(float velocity) {
+ ui::GestureEvent event(0, last_y_, ui::EF_NONE, base::TimeDelta(),
+ ui::GestureEventDetails(
+ ui::ET_SCROLL_FLING_START, 0, velocity));
+ gesture_manager_->ProcessGestureEvent(&event);
+ }
+
+ HomeCard::State final_state_;
+ HomeCard::State last_from_state_;
+ HomeCard::State last_to_state_;
+ float last_progress_;
+
+ private:
+ gfx::Rect screen_bounds() const {
+ return gfx::Rect(0, 0, 1280, 1024);
+ }
+
+ // HomeCardGestureManager::Delegate:
+ virtual void OnGestureEnded(HomeCard::State final_state) OVERRIDE {
+ final_state_ = final_state;
+ ++end_count_;
+ }
+
+ virtual void OnGestureProgressed(HomeCard::State from_state,
+ HomeCard::State to_state,
+ float progress) OVERRIDE {
+ last_from_state_ = from_state;
+ last_to_state_ = to_state;
+ last_progress_ = progress;
+ ++progress_count_;
+ }
+
+ int last_y_;
+ int progress_count_;
+ int end_count_;
+ scoped_ptr<HomeCardGestureManager> gesture_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(HomeCardGestureManagerTest);
+};
+
+TEST_F(HomeCardGestureManagerTest, Basic) {
+ EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 1020));
+ EXPECT_EQ(0, GetEndCountAndReset());
+ EXPECT_EQ(0, GetProgressCountAndReset());
+
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1019);
+ EXPECT_EQ(1, GetProgressCountAndReset());
+ EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, last_from_state_);
+ EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_to_state_);
+ EXPECT_GT(1.0f, last_progress_);
+
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1010);
+ float progress_1010 = last_progress_;
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1008);
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1000);
+ EXPECT_EQ(3, GetProgressCountAndReset());
+ EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, last_from_state_);
+ EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_to_state_);
+ EXPECT_LT(progress_1010, last_progress_);
+
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 900);
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 800);
+ EXPECT_EQ(2, GetProgressCountAndReset());
+ EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_);
+ EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_);
+ float progress_800 = last_progress_;
+ EXPECT_GT(1.0f, last_progress_);
+ EXPECT_LT(0.0f, last_progress_);
+
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 790);
+ EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_);
+ EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_);
+ EXPECT_LT(progress_800, last_progress_);
+
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 810);
+ EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_from_state_);
+ EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_to_state_);
+ EXPECT_GT(progress_800, (1.0f - last_progress_));
+
+ EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 810));
+ EXPECT_EQ(1, GetEndCountAndReset());
+ EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_);
+}
+
+TEST_F(HomeCardGestureManagerTest, FlingUpAtEnd) {
+ EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 1020));
+ EXPECT_EQ(0, GetEndCountAndReset());
+ EXPECT_EQ(0, GetProgressCountAndReset());
+
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1010);
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 800);
+ ProcessFlingGesture(-150.0f);
+ EXPECT_EQ(1, GetEndCountAndReset());
+ EXPECT_EQ(HomeCard::VISIBLE_CENTERED, final_state_);
+}
+
+TEST_F(HomeCardGestureManagerTest, FlingDownAtEnd) {
+ EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 1020));
+ EXPECT_EQ(0, GetEndCountAndReset());
+ EXPECT_EQ(0, GetProgressCountAndReset());
+
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1010);
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 800);
+ ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 200);
+ ProcessFlingGesture(150.0f);
+ EXPECT_EQ(1, GetEndCountAndReset());
+ EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_);
+}
+
+} // namespace athena
diff --git a/athena/home/home_card_impl.cc b/athena/home/home_card_impl.cc
index f98e4ab..2078325 100644
--- a/athena/home/home_card_impl.cc
+++ b/athena/home/home_card_impl.cc
@@ -11,6 +11,8 @@
#include "athena/env/public/athena_env.h"
#include "athena/home/app_list_view_delegate.h"
#include "athena/home/athena_start_page_view.h"
+#include "athena/home/home_card_constants.h"
+#include "athena/home/home_card_gesture_manager.h"
#include "athena/home/minimized_home.h"
#include "athena/home/public/app_model_builder.h"
#include "athena/input/public/accelerator_manager.h"
@@ -40,8 +42,6 @@ namespace athena {
namespace {
HomeCard* instance = NULL;
-const int kHomeCardHeight = 100;
-const int kHomeCardMinimizedHeight = 6;
gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds,
HomeCard::State state) {
@@ -122,151 +122,6 @@ class HomeCardLayoutManager : public aura::LayoutManager {
DISALLOW_COPY_AND_ASSIGN(HomeCardLayoutManager);
};
-class HomeCardGestureManager {
- public:
- class Delegate {
- public:
- // Called when the gesture has ended. The state of the home card will
- // end up with |final_state|.
- virtual void OnGestureEnded(HomeCard::State final_state) = 0;
-
- // Called when the gesture position is updated so that |delegate| should
- // update the visual. The arguments represent the state of the current
- // gesture position is switching from |from_state| to |to_state|, and
- // the level of the progress is at |progress|, which is 0 to 1.
- // |from_state| and |to_state| could be same. For example, if the user moves
- // the finger down to the bottom of the screen, both states are MINIMIZED.
- // In that case |progress| is 0.
- virtual void OnGestureProgressed(
- HomeCard::State from_state,
- HomeCard::State to_state,
- float progress) = 0;
- };
-
- HomeCardGestureManager(Delegate* delegate,
- const gfx::Rect& screen_bounds)
- : delegate_(delegate),
- last_state_(HomeCard::Get()->GetState()),
- y_offset_(0),
- last_estimated_top_(0),
- screen_bounds_(screen_bounds) {}
-
- void ProcessGestureEvent(ui::GestureEvent* event) {
- switch (event->type()) {
- case ui::ET_GESTURE_SCROLL_BEGIN:
- y_offset_ = event->location().y();
- event->SetHandled();
- break;
- case ui::ET_GESTURE_SCROLL_END:
- event->SetHandled();
- delegate_->OnGestureEnded(GetClosestState());
- break;
- case ui::ET_GESTURE_SCROLL_UPDATE:
- UpdateScrollState(*event);
- break;
- case ui::ET_SCROLL_FLING_START: {
- const ui::GestureEventDetails& details = event->details();
- const float kFlingCompletionVelocity = 100.0f;
- if (::fabs(details.velocity_y()) > kFlingCompletionVelocity) {
- int step = (details.velocity_y() > 0) ? 1 : -1;
- int new_state = static_cast<int>(last_state_) + step;
- if (new_state >= HomeCard::VISIBLE_CENTERED &&
- new_state <= HomeCard::VISIBLE_MINIMIZED) {
- last_state_ = static_cast<HomeCard::State>(new_state);
- }
- delegate_->OnGestureEnded(last_state_);
- }
- break;
- }
- default:
- // do nothing.
- break;
- }
- }
-
- private:
- HomeCard::State GetClosestState() {
- // The top position of the bounds for one smaller state than the current
- // one.
- int smaller_top = -1;
- for (int i = HomeCard::VISIBLE_MINIMIZED;
- i >= HomeCard::VISIBLE_CENTERED; --i) {
- HomeCard::State state = static_cast<HomeCard::State>(i);
- int top = GetBoundsForState(screen_bounds_, state).y();
- if (last_estimated_top_ == top) {
- return state;
- } else if (last_estimated_top_ > top) {
- if (smaller_top < 0)
- return state;
-
- if (smaller_top - last_estimated_top_ > (smaller_top - top) / 5) {
- return state;
- } else {
- return static_cast<HomeCard::State>(i + 1);
- }
- }
- smaller_top = top;
- }
-
- return last_state_;
- }
-
- void UpdateScrollState(const ui::GestureEvent& event) {
- last_estimated_top_ = event.root_location().y() - y_offset_;
-
- // The bounds which is at one smaller state than the current one.
- gfx::Rect smaller_bounds;
-
- for (int i = HomeCard::VISIBLE_MINIMIZED;
- i >= HomeCard::VISIBLE_CENTERED; --i) {
- HomeCard::State state = static_cast<HomeCard::State>(i);
- const gfx::Rect bounds = GetBoundsForState(screen_bounds_, state);
- if (last_estimated_top_ == bounds.y()) {
- delegate_->OnGestureProgressed(last_state_, state, 1.0f);
- last_state_ = state;
- return;
- } else if (last_estimated_top_ > bounds.y()) {
- if (smaller_bounds.IsEmpty()) {
- // Smaller than minimized -- returning the minimized bounds.
- delegate_->OnGestureProgressed(last_state_, state, 1.0f);
- } else {
- // The finger is between two states.
- float progress =
- static_cast<float>((smaller_bounds.y() - last_estimated_top_)) /
- (smaller_bounds.y() - bounds.y());
- if (last_state_ == state) {
- if (event.details().scroll_y() > 0) {
- state = static_cast<HomeCard::State>(state + 1);
- progress = 1.0f - progress;
- } else {
- last_state_ = static_cast<HomeCard::State>(last_state_ + 1);
- }
- }
- delegate_->OnGestureProgressed(last_state_, state, progress);
- }
- last_state_ = state;
- return;
- }
- smaller_bounds = bounds;
- }
- }
-
- Delegate* delegate_;
- HomeCard::State last_state_;
-
- // The offset from the top edge of the home card and the initial position of
- // gesture.
- int y_offset_;
-
- // The estimated top edge of the home card after the last touch event.
- int last_estimated_top_;
-
- // The bounds of the screen to compute the home card bounds.
- gfx::Rect screen_bounds_;
-
- DISALLOW_COPY_AND_ASSIGN(HomeCardGestureManager);
-};
-
// The container view of home card contents of each state.
class HomeCardView : public views::WidgetDelegateView {
public: