Chromium Code Reviews| Index: ui/touch_selection/longpress_drag_selector.cc |
| diff --git a/ui/touch_selection/longpress_drag_selector.cc b/ui/touch_selection/longpress_drag_selector.cc |
| index ad68171a61910f198ed457e0003466b8895cf967..0ff82484ac284f932ef902327544adf076970dc6 100644 |
| --- a/ui/touch_selection/longpress_drag_selector.cc |
| +++ b/ui/touch_selection/longpress_drag_selector.cc |
| @@ -8,6 +8,13 @@ |
| #include "ui/events/gesture_detection/motion_event.h" |
| namespace ui { |
| +namespace { |
| + |
| +gfx::Vector2dF SafeNormalize(const gfx::Vector2dF& v) { |
| + return v.IsZero() ? v : ScaleVector2d(v, 1.f / v.Length()); |
| +} |
| + |
| +} // namespace |
| LongPressDragSelector::LongPressDragSelector( |
| LongPressDragSelectorClient* client) |
| @@ -70,21 +77,28 @@ bool LongPressDragSelector::WillHandleTouchEvent(const MotionEvent& event) { |
| // If initial motion is up/down, extend the start/end selection bound. |
| extend_selection_start = delta.y() < 0; |
| } else { |
| - // Otherwise extend the selection bound toward which we're moving. |
| + // Otherwise extend the selection bound toward which we're moving, or |
| + // the closest bound if motion is already away from both bounds. |
| // Note that, for mixed RTL text, or for multiline selections triggered |
| // by longpress, this may not pick the most suitable drag target |
| gfx::Vector2dF start_delta = selection_start - position; |
| - |
| - // The vectors must be normalized to make dot product comparison meaningful. |
| - if (!start_delta.IsZero()) |
| - start_delta.Scale(1.f / start_delta.Length()); |
| gfx::Vector2dF end_delta = selection_end - position; |
| - if (!end_delta.IsZero()) |
| - end_delta.Scale(1.f / start_delta.Length()); |
| - // The larger the dot product the more similar the direction. |
| - extend_selection_start = |
| - gfx::DotProduct(start_delta, delta) > gfx::DotProduct(end_delta, delta); |
| + // The vectors must be normalized to make dot product comparison meaningful. |
| + gfx::Vector2dF normalized_start_delta = SafeNormalize(start_delta); |
| + gfx::Vector2dF normalized_end_delta = SafeNormalize(end_delta); |
| + double start_dot_product = gfx::DotProduct(normalized_start_delta, delta); |
| + double end_dot_product = gfx::DotProduct(normalized_end_delta, delta); |
| + |
| + if (start_dot_product < 0 && end_dot_product < 0) { |
|
mfomitchev
2015/08/04 18:31:36
nit: It makes it a bit harder to parse when the or
jdduke (slow)
2015/08/04 19:14:51
Done.
|
| + // If we're already moving away from both endpoints, pick the closest. |
| + extend_selection_start = |
| + start_delta.LengthSquared() < end_delta.LengthSquared(); |
| + } else { |
| + // Otherwise pick the endpoint toward we're which moving. The larger the |
| + // dot product the more similar the direction. |
| + extend_selection_start = start_dot_product > end_dot_product; |
| + } |
| } |
| gfx::PointF extent = extend_selection_start ? selection_start : selection_end; |