1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/events/gesture_detection/snap_scroll_controller.h"
9 #include "ui/events/gesture_detection/motion_event.h"
10 #include "ui/gfx/display.h"
14 const int kSnapBound
= 16;
15 const float kMinSnapChannelDistance
= kSnapBound
;
16 const float kMaxSnapChannelDistance
= kMinSnapChannelDistance
* 3.f
;
17 const float kSnapChannelDipsPerScreenDip
= kMinSnapChannelDistance
/ 480.f
;
19 float CalculateChannelDistance(const gfx::Display
& display
) {
20 if (display
.bounds().IsEmpty())
21 return kMinSnapChannelDistance
;
24 std::abs(hypot(static_cast<float>(display
.bounds().width()),
25 static_cast<float>(display
.bounds().height())));
27 float snap_channel_distance
= screen_size
* kSnapChannelDipsPerScreenDip
;
28 return std::max(kMinSnapChannelDistance
,
29 std::min(kMaxSnapChannelDistance
, snap_channel_distance
));
35 SnapScrollController::SnapScrollController(const gfx::Display
& display
)
36 : channel_distance_(CalculateChannelDistance(display
)),
37 snap_scroll_mode_(SNAP_NONE
),
43 SnapScrollController::~SnapScrollController() {}
45 void SnapScrollController::UpdateSnapScrollMode(float distance_x
,
47 if (snap_scroll_mode_
== SNAP_HORIZ
|| snap_scroll_mode_
== SNAP_VERT
) {
48 distance_x_
+= std::abs(distance_x
);
49 distance_y_
+= std::abs(distance_y
);
50 if (snap_scroll_mode_
== SNAP_HORIZ
) {
51 if (distance_y_
> channel_distance_
) {
52 snap_scroll_mode_
= SNAP_NONE
;
53 } else if (distance_x_
> channel_distance_
) {
58 if (distance_x_
> channel_distance_
) {
59 snap_scroll_mode_
= SNAP_NONE
;
60 } else if (distance_y_
> channel_distance_
) {
68 void SnapScrollController::SetSnapScrollingMode(
69 const MotionEvent
& event
,
70 bool is_scale_gesture_detection_in_progress
) {
71 switch (event
.GetAction()) {
72 case MotionEvent::ACTION_DOWN
:
73 snap_scroll_mode_
= SNAP_NONE
;
74 first_touch_x_
= event
.GetX();
75 first_touch_y_
= event
.GetY();
77 // Set scrolling mode to SNAP_X if scroll towards x-axis exceeds kSnapBound
78 // and movement towards y-axis is trivial.
79 // Set scrolling mode to SNAP_Y if scroll towards y-axis exceeds kSnapBound
80 // and movement towards x-axis is trivial.
81 // Scrolling mode will remain in SNAP_NONE for other conditions.
82 case MotionEvent::ACTION_MOVE
:
83 if (!is_scale_gesture_detection_in_progress
&&
84 snap_scroll_mode_
== SNAP_NONE
) {
85 int x_diff
= static_cast<int>(std::abs(event
.GetX() - first_touch_x_
));
86 int y_diff
= static_cast<int>(std::abs(event
.GetY() - first_touch_y_
));
87 if (x_diff
> kSnapBound
&& y_diff
< kSnapBound
) {
88 snap_scroll_mode_
= SNAP_HORIZ
;
89 } else if (x_diff
< kSnapBound
&& y_diff
> kSnapBound
) {
90 snap_scroll_mode_
= SNAP_VERT
;
94 case MotionEvent::ACTION_UP
:
95 case MotionEvent::ACTION_CANCEL
: