1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "athena/home/home_card_gesture_manager.h"
7 #include "athena/home/home_card_constants.h"
8 #include "ui/events/event.h"
14 // The maximum height, in pixels, of a home card with final state
16 const int kMinimizedFinalStateMaxHeight
= 50 + kHomeCardMinimizedHeight
;
18 // The maximum height, in pixels, of an initially centered home card with final
19 // state VISIBLE_MINIMIZED.
20 const int kMinimizedFinalStateMaxHeightInitiallyCentered
=
21 90 + kHomeCardMinimizedHeight
;
23 // The minimum height, as a percentage of the screen height, of a home card with
24 // final state VISIBLE_CENTERED.
25 const float kCenteredFinalStateMinScreenRatio
= 0.5f
;
27 // The minimum height, as a percentage of the screen height, of an initially
28 // minimized home card with final state VISIBLE_CENTERED.
29 const float kCenteredFinalStateMinScreenRatioInitiallyMinimized
= 0.3f
;
33 HomeCardGestureManager::HomeCardGestureManager(Delegate
* delegate
,
34 const gfx::Rect
& screen_bounds
)
35 : delegate_(delegate
),
36 original_state_(HomeCard::HIDDEN
),
38 last_estimated_height_(0),
39 screen_bounds_(screen_bounds
) {}
41 HomeCardGestureManager::~HomeCardGestureManager() {}
43 void HomeCardGestureManager::ProcessGestureEvent(ui::GestureEvent
* event
) {
44 switch (event
->type()) {
45 case ui::ET_GESTURE_SCROLL_BEGIN
:
46 y_offset_
= event
->location().y();
47 original_state_
= HomeCard::Get()->GetState();
48 DCHECK_NE(HomeCard::HIDDEN
, original_state_
);
51 case ui::ET_GESTURE_SCROLL_END
:
53 delegate_
->OnGestureEnded(GetFinalState(), false);
55 case ui::ET_GESTURE_SCROLL_UPDATE
:
56 UpdateScrollState(*event
);
58 case ui::ET_SCROLL_FLING_START
: {
59 const ui::GestureEventDetails
& details
= event
->details();
60 const float kFlingCompletionVelocity
= 100.0f
;
61 HomeCard::State final_state
= GetFinalState();
63 // When the user does not drag far enough to switch the final state, but
64 // a fling happens at the end of the gesture, the state should change
65 // based on the direction of the fling.
66 // Checking |final_state| == |original_state| may cause unexpected results
67 // for gestures where the user flings in the opposite direction that they
68 // moved the home card (e.g. drag home card up from minimized state and
70 // TODO(mukai): Consider this case once reported.
71 bool is_fling
= ::fabs(details
.velocity_y()) > kFlingCompletionVelocity
;
72 if (final_state
== original_state_
&& is_fling
) {
73 if (details
.velocity_y() > 0) {
74 final_state
= std::min(HomeCard::VISIBLE_MINIMIZED
,
75 static_cast<HomeCard::State
>(final_state
+ 1));
77 final_state
= std::max(HomeCard::VISIBLE_CENTERED
,
78 static_cast<HomeCard::State
>(final_state
- 1));
81 delegate_
->OnGestureEnded(final_state
, is_fling
);
90 HomeCard::State
HomeCardGestureManager::GetFinalState() const {
91 int max_height
= (original_state_
== HomeCard::VISIBLE_CENTERED
)
92 ? kMinimizedFinalStateMaxHeightInitiallyCentered
93 : kMinimizedFinalStateMaxHeight
;
94 if (last_estimated_height_
< max_height
)
95 return HomeCard::VISIBLE_MINIMIZED
;
97 float ratio
= (original_state_
== HomeCard::VISIBLE_MINIMIZED
)
98 ? kCenteredFinalStateMinScreenRatioInitiallyMinimized
99 : kCenteredFinalStateMinScreenRatio
;
100 if (last_estimated_height_
< screen_bounds_
.height() * ratio
)
101 return HomeCard::VISIBLE_BOTTOM
;
103 return HomeCard::VISIBLE_CENTERED
;
106 void HomeCardGestureManager::UpdateScrollState(const ui::GestureEvent
& event
) {
107 last_estimated_height_
=
108 screen_bounds_
.height() - event
.root_location().y() + y_offset_
;
110 if (last_estimated_height_
<= kHomeCardMinimizedHeight
) {
111 delegate_
->OnGestureProgressed(
112 HomeCard::VISIBLE_BOTTOM
, HomeCard::VISIBLE_MINIMIZED
, 1.0f
);
116 HomeCard::State bigger_state
= HomeCard::VISIBLE_BOTTOM
;
117 float smaller_height
= kHomeCardMinimizedHeight
;
118 float bigger_height
= kHomeCardHeight
;
119 if (last_estimated_height_
> kHomeCardHeight
) {
120 bigger_state
= HomeCard::VISIBLE_CENTERED
;
121 smaller_height
= kHomeCardHeight
;
122 bigger_height
= screen_bounds_
.height();
125 // The finger is between two states.
126 float progress
= (last_estimated_height_
- smaller_height
) /
127 (bigger_height
- smaller_height
);
128 progress
= std::min(1.0f
, std::max(0.0f
, progress
));
130 delegate_
->OnGestureProgressed(
131 static_cast<HomeCard::State
>(bigger_state
+ 1),
136 } // namespace athena