Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Unified Diff: ui/events/gesture_detection/snap_scroll_controller.cc

Issue 1287103004: Sync ui/events to chromium @ https://codereview.chromium.org/1210203002 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/events/gesture_detection/snap_scroll_controller.cc
diff --git a/ui/events/gesture_detection/snap_scroll_controller.cc b/ui/events/gesture_detection/snap_scroll_controller.cc
index bde5a35602d6579cef87173f6fe7ed44c6755cf6..9ecf6b108c8a71030bc282bda1dbc1c5f065696a 100644
--- a/ui/events/gesture_detection/snap_scroll_controller.cc
+++ b/ui/events/gesture_detection/snap_scroll_controller.cc
@@ -7,100 +7,118 @@
#include <cmath>
#include "ui/events/gesture_detection/motion_event.h"
-#include "ui/gfx/display.h"
namespace ui {
namespace {
-const int kSnapBound = 16;
-const float kMinSnapChannelDistance = kSnapBound;
-const float kMaxSnapChannelDistance = kMinSnapChannelDistance * 3.f;
-const float kSnapChannelDipsPerScreenDip = kMinSnapChannelDistance / 480.f;
-float CalculateChannelDistance(const gfx::Display& display) {
- if (display.bounds().IsEmpty())
- return kMinSnapChannelDistance;
+// Minimum ratio between initial X and Y motion to allow snapping.
+const float kMinSnapRatio = 1.25f;
+
+// Size of the snap rail relative to the initial snap bound threshold.
+const float kSnapBoundToChannelMultiplier = 1.5f;
+
+float CalculateChannelDistance(float snap_bound,
+ const gfx::SizeF& display_size) {
+ const float kMinChannelDistance = snap_bound * kSnapBoundToChannelMultiplier;
+ const float kMaxChannelDistance = kMinChannelDistance * 3.f;
+ const float kSnapChannelDipsPerScreenDip = kMinChannelDistance / 480.f;
+ if (display_size.IsEmpty())
+ return kMinChannelDistance;
float screen_size =
- std::abs(hypot(static_cast<float>(display.bounds().width()),
- static_cast<float>(display.bounds().height())));
+ std::abs(hypot(static_cast<float>(display_size.width()),
+ static_cast<float>(display_size.height())));
float snap_channel_distance = screen_size * kSnapChannelDipsPerScreenDip;
- return std::max(kMinSnapChannelDistance,
- std::min(kMaxSnapChannelDistance, snap_channel_distance));
+ return std::max(kMinChannelDistance,
+ std::min(kMaxChannelDistance, snap_channel_distance));
}
} // namespace
+SnapScrollController::SnapScrollController(float snap_bound,
+ const gfx::SizeF& display_size)
+ : snap_bound_(snap_bound),
+ channel_distance_(CalculateChannelDistance(snap_bound, display_size)),
+ mode_(SNAP_NONE) {
+}
-SnapScrollController::SnapScrollController(const gfx::Display& display)
- : channel_distance_(CalculateChannelDistance(display)),
- snap_scroll_mode_(SNAP_NONE),
- first_touch_x_(-1),
- first_touch_y_(-1),
- distance_x_(0),
- distance_y_(0) {}
-
-SnapScrollController::~SnapScrollController() {}
-
-void SnapScrollController::UpdateSnapScrollMode(float distance_x,
- float distance_y) {
- if (snap_scroll_mode_ == SNAP_HORIZ || snap_scroll_mode_ == SNAP_VERT) {
- distance_x_ += std::abs(distance_x);
- distance_y_ += std::abs(distance_y);
- if (snap_scroll_mode_ == SNAP_HORIZ) {
- if (distance_y_ > channel_distance_) {
- snap_scroll_mode_ = SNAP_NONE;
- } else if (distance_x_ > channel_distance_) {
- distance_x_ = 0;
- distance_y_ = 0;
- }
- } else {
- if (distance_x_ > channel_distance_) {
- snap_scroll_mode_ = SNAP_NONE;
- } else if (distance_y_ > channel_distance_) {
- distance_x_ = 0;
- distance_y_ = 0;
- }
- }
- }
+SnapScrollController::~SnapScrollController() {
}
-void SnapScrollController::SetSnapScrollingMode(
+void SnapScrollController::SetSnapScrollMode(
const MotionEvent& event,
bool is_scale_gesture_detection_in_progress) {
switch (event.GetAction()) {
case MotionEvent::ACTION_DOWN:
- snap_scroll_mode_ = SNAP_NONE;
- first_touch_x_ = event.GetX();
- first_touch_y_ = event.GetY();
+ mode_ = SNAP_PENDING;
+ down_position_.set_x(event.GetX());
+ down_position_.set_y(event.GetY());
break;
- // Set scrolling mode to SNAP_X if scroll towards x-axis exceeds kSnapBound
- // and movement towards y-axis is trivial.
- // Set scrolling mode to SNAP_Y if scroll towards y-axis exceeds kSnapBound
- // and movement towards x-axis is trivial.
- // Scrolling mode will remain in SNAP_NONE for other conditions.
- case MotionEvent::ACTION_MOVE:
- if (!is_scale_gesture_detection_in_progress &&
- snap_scroll_mode_ == SNAP_NONE) {
- int x_diff = static_cast<int>(std::abs(event.GetX() - first_touch_x_));
- int y_diff = static_cast<int>(std::abs(event.GetY() - first_touch_y_));
- if (x_diff > kSnapBound && y_diff < kSnapBound) {
- snap_scroll_mode_ = SNAP_HORIZ;
- } else if (x_diff < kSnapBound && y_diff > kSnapBound) {
- snap_scroll_mode_ = SNAP_VERT;
- }
+ case MotionEvent::ACTION_MOVE: {
+ if (is_scale_gesture_detection_in_progress)
+ break;
+
+ if (mode_ != SNAP_PENDING)
+ break;
+
+ // Set scrolling mode to SNAP_X if scroll exceeds |snap_bound_| and the
+ // ratio of x movement to y movement is sufficiently large. Similarly for
+ // SNAP_Y and y movement.
+ float dx = std::abs(event.GetX() - down_position_.x());
+ float dy = std::abs(event.GetY() - down_position_.y());
+ float kMinSnapBound = snap_bound_;
+ float kMaxSnapBound = snap_bound_ * 2.f;
+ if (dx * dx + dy * dy > kMinSnapBound * kMinSnapBound) {
+ if (!dy || (dx / dy > kMinSnapRatio && dy < kMaxSnapBound))
+ mode_ = SNAP_HORIZ;
+ else if (!dx || (dy / dx > kMinSnapRatio && dx < kMaxSnapBound))
+ mode_ = SNAP_VERT;
}
- break;
+
+ if (mode_ == SNAP_PENDING && dx > kMaxSnapBound && dy > kMaxSnapBound)
+ mode_ = SNAP_NONE;
+ } break;
case MotionEvent::ACTION_UP:
case MotionEvent::ACTION_CANCEL:
- first_touch_x_ = -1;
- first_touch_y_ = -1;
- distance_x_ = 0;
- distance_y_ = 0;
+ down_position_ = gfx::PointF();
+ accumulated_distance_ = gfx::Vector2dF();
break;
default:
break;
}
}
+void SnapScrollController::UpdateSnapScrollMode(float distance_x,
+ float distance_y) {
+ if (!IsSnappingScrolls())
+ return;
+
+ accumulated_distance_ +=
+ gfx::Vector2dF(std::abs(distance_x), std::abs(distance_y));
+ if (mode_ == SNAP_HORIZ) {
+ if (accumulated_distance_.y() > channel_distance_)
+ mode_ = SNAP_NONE;
+ else if (accumulated_distance_.x() > channel_distance_)
+ accumulated_distance_ = gfx::Vector2dF();
+ } else if (mode_ == SNAP_VERT) {
+ if (accumulated_distance_.x() > channel_distance_)
+ mode_ = SNAP_NONE;
+ else if (accumulated_distance_.y() > channel_distance_)
+ accumulated_distance_ = gfx::Vector2dF();
+ }
+}
+
+bool SnapScrollController::IsSnapVertical() const {
+ return mode_ == SNAP_VERT;
+}
+
+bool SnapScrollController::IsSnapHorizontal() const {
+ return mode_ == SNAP_HORIZ;
+}
+
+bool SnapScrollController::IsSnappingScrolls() const {
+ return IsSnapHorizontal() || IsSnapVertical();
+}
+
} // namespace ui
« no previous file with comments | « ui/events/gesture_detection/snap_scroll_controller.h ('k') | ui/events/gesture_detection/snap_scroll_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698