Chromium Code Reviews| Index: ui/touch_selection/touch_selection_controller.cc |
| diff --git a/ui/touch_selection/touch_selection_controller.cc b/ui/touch_selection/touch_selection_controller.cc |
| index 3d52b4c3e423f276b65541c1491b0e260411fb86..20368d67dc34d75aaffb8afcd4de518e452b4d1c 100644 |
| --- a/ui/touch_selection/touch_selection_controller.cc |
| +++ b/ui/touch_selection/touch_selection_controller.cc |
| @@ -47,7 +47,7 @@ TouchSelectionController::TouchSelectionController( |
| bool show_on_tap_for_empty_editable) |
| : client_(client), |
| tap_timeout_(tap_timeout), |
| - tap_slop_(tap_slop), |
| + tap_slop_squared_(static_cast<double>(tap_slop) * tap_slop), |
| show_on_tap_for_empty_editable_(show_on_tap_for_empty_editable), |
| response_pending_input_event_(INPUT_EVENT_TYPE_NONE), |
| start_orientation_(TouchHandleOrientation::UNDEFINED), |
| @@ -59,6 +59,7 @@ TouchSelectionController::TouchSelectionController( |
| selection_empty_(false), |
| selection_editable_(false), |
| temporarily_hidden_(false), |
| + longpress_drag_selector_(this), |
| selection_handle_dragged_(false) { |
| DCHECK(client_); |
| } |
| @@ -92,8 +93,8 @@ void TouchSelectionController::OnSelectionBoundsChanged( |
| &response_pending_input_event_, causal_input_event); |
| const bool is_selection_dragging = |
| - is_selection_active_ && (start_selection_handle_->is_dragging() || |
| - end_selection_handle_->is_dragging()); |
| + is_selection_active_ && (start_selection_handle_->IsDragging() || |
| + end_selection_handle_->IsDragging()); |
| // It's possible that the bounds temporarily overlap while a selection handle |
| // is being dragged, incorrectly reporting a CENTER orientation. |
| @@ -126,6 +127,9 @@ void TouchSelectionController::OnSelectionBoundsChanged( |
| } |
| bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) { |
| + if (longpress_drag_selector_.WillHandleTouchEvent(event)) |
| + return true; |
| + |
| if (is_insertion_active_) { |
| DCHECK(insertion_handle_); |
| return insertion_handle_->WillHandleTouchEvent(event); |
| @@ -134,10 +138,10 @@ bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) { |
| if (is_selection_active_) { |
| DCHECK(start_selection_handle_); |
| DCHECK(end_selection_handle_); |
| - if (start_selection_handle_->is_dragging()) |
| + if (start_selection_handle_->IsDragging()) |
| return start_selection_handle_->WillHandleTouchEvent(event); |
| - if (end_selection_handle_->is_dragging()) |
| + if (end_selection_handle_->IsDragging()) |
| return end_selection_handle_->WillHandleTouchEvent(event); |
| const gfx::PointF event_pos(event.GetX(), event.GetY()); |
| @@ -151,7 +155,9 @@ bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) { |
| return false; |
| } |
| -void TouchSelectionController::OnLongPressEvent() { |
| +void TouchSelectionController::OnLongPressEvent(base::TimeTicks event_time, |
| + const gfx::PointF& position) { |
| + longpress_drag_selector_.OnLongPressEvent(event_time, position); |
| response_pending_input_event_ = LONG_PRESS; |
| ShowSelectionHandlesAutomatically(); |
| ShowInsertionHandleAutomatically(); |
| @@ -191,14 +197,7 @@ void TouchSelectionController::SetTemporarilyHidden(bool hidden) { |
| if (temporarily_hidden_ == hidden) |
| return; |
| temporarily_hidden_ = hidden; |
| - |
| - TouchHandle::AnimationStyle animation_style = GetAnimationStyle(true); |
| - if (is_selection_active_) { |
| - start_selection_handle_->SetVisible(GetStartVisible(), animation_style); |
| - end_selection_handle_->SetVisible(GetEndVisible(), animation_style); |
| - } |
| - if (is_insertion_active_) |
| - insertion_handle_->SetVisible(GetStartVisible(), animation_style); |
| + RefreshHandleVisibility(); |
| } |
| void TouchSelectionController::OnSelectionEditable(bool editable) { |
| @@ -269,20 +268,38 @@ const gfx::PointF& TouchSelectionController::GetEndPosition() const { |
| return end_.edge_bottom(); |
| } |
| -void TouchSelectionController::OnHandleDragBegin(const TouchHandle& handle) { |
| - if (&handle == insertion_handle_.get()) { |
| +void TouchSelectionController::OnDragBegin( |
| + const TouchSelectionDraggable& draggable, |
| + const gfx::PointF& drag_position) { |
| + if (&draggable == insertion_handle_.get()) { |
| client_->OnSelectionEvent(INSERTION_DRAG_STARTED); |
| + drag_line_offset_ = GetStartLineOffset(); |
| return; |
| } |
| - gfx::PointF base, extent; |
| - if (&handle == start_selection_handle_.get()) { |
| - base = end_selection_handle_->position() + GetEndLineOffset(); |
| - extent = start_selection_handle_->position() + GetStartLineOffset(); |
| + DCHECK(is_selection_active_); |
| + |
| + bool extend_selection_start = false; |
| + if (&draggable == start_selection_handle_.get()) { |
| + extend_selection_start = true; |
| + } else if (&draggable == end_selection_handle_.get()) { |
| + extend_selection_start = false; |
| + } else { |
| + DCHECK_EQ(&draggable, &longpress_drag_selector_); |
| + extend_selection_start = |
| + (drag_position - GetStartPosition()).LengthSquared() < |
| + (drag_position - GetEndPosition()).LengthSquared(); |
| + } |
| + |
| + gfx::PointF base = GetStartPosition() + GetStartLineOffset(); |
| + gfx::PointF extent = GetEndPosition() + GetEndLineOffset(); |
| + if (extend_selection_start) { |
| + std::swap(base, extent); |
| + drag_line_offset_ = GetStartLineOffset(); |
| } else { |
| - base = start_selection_handle_->position() + GetStartLineOffset(); |
| - extent = end_selection_handle_->position() + GetEndLineOffset(); |
| + drag_line_offset_ = GetEndLineOffset(); |
| } |
| + |
| selection_handle_dragged_ = true; |
| // When moving the handle we want to move only the extent point. Before doing |
| @@ -291,28 +308,32 @@ void TouchSelectionController::OnHandleDragBegin(const TouchHandle& handle) { |
| client_->OnSelectionEvent(SELECTION_DRAG_STARTED); |
| } |
| -void TouchSelectionController::OnHandleDragUpdate(const TouchHandle& handle, |
| - const gfx::PointF& position) { |
| +void TouchSelectionController::OnDragUpdate( |
| + const TouchSelectionDraggable& draggable, |
| + const gfx::PointF& drag_position) { |
| // As the position corresponds to the bottom left point of the selection |
| // bound, offset it by half the corresponding line height. |
| - gfx::Vector2dF line_offset = &handle == start_selection_handle_.get() |
| - ? GetStartLineOffset() |
| - : GetEndLineOffset(); |
| - gfx::PointF line_position = position + line_offset; |
| - if (&handle == insertion_handle_.get()) { |
| + gfx::PointF line_position = drag_position + drag_line_offset_; |
| + if (&draggable == insertion_handle_.get()) { |
| client_->MoveCaret(line_position); |
| } else { |
| client_->MoveRangeSelectionExtent(line_position); |
| } |
| } |
| -void TouchSelectionController::OnHandleDragEnd(const TouchHandle& handle) { |
| - if (&handle == insertion_handle_.get()) |
| +void TouchSelectionController::OnDragEnd( |
| + const TouchSelectionDraggable& draggable) { |
| + if (&draggable == insertion_handle_.get()) |
| client_->OnSelectionEvent(INSERTION_DRAG_STOPPED); |
| else |
| client_->OnSelectionEvent(SELECTION_DRAG_STOPPED); |
| } |
| +bool TouchSelectionController::IsWithinTapSlop( |
| + const gfx::Vector2dF& delta) const { |
| + return delta.LengthSquared() < tap_slop_squared_; |
| +} |
| + |
| void TouchSelectionController::OnHandleTapped(const TouchHandle& handle) { |
| if (insertion_handle_ && &handle == insertion_handle_.get()) |
| client_->OnSelectionEvent(INSERTION_TAPPED); |
| @@ -330,8 +351,18 @@ base::TimeDelta TouchSelectionController::GetTapTimeout() const { |
| return tap_timeout_; |
| } |
| -float TouchSelectionController::GetTapSlop() const { |
| - return tap_slop_; |
| +void TouchSelectionController::OnLongPressDragDetectionStateChanged() { |
|
mfomitchev
2015/04/28 02:17:30
I don't understand why we need this. TSC::OnSelect
jdduke (slow)
2015/04/28 20:37:48
The problem is that we want the handles to reappea
mfomitchev
2015/04/29 00:34:28
Ah, I see, thanks for explaining. I am fine with i
|
| + // The handles should remain hidden for the duration of a longpress drag, |
| + // including the time between a longpress and the start of drag motion. |
| + RefreshHandleVisibility(); |
| +} |
| + |
| +gfx::PointF TouchSelectionController::GetSelectionStart() const { |
| + return GetStartPosition(); |
| +} |
| + |
| +gfx::PointF TouchSelectionController::GetSelectionEnd() const { |
| + return GetEndPosition(); |
| } |
| void TouchSelectionController::ShowInsertionHandleAutomatically() { |
| @@ -444,6 +475,7 @@ void TouchSelectionController::ActivateSelection() { |
| selection_handle_dragged_ = false; |
| selection_start_time_ = base::TimeTicks::Now(); |
| response_pending_input_event_ = INPUT_EVENT_TYPE_NONE; |
| + longpress_drag_selector_.OnSelectionActivated(); |
| client_->OnSelectionEvent(SELECTION_SHOWN); |
| } |
| } |
| @@ -454,6 +486,7 @@ void TouchSelectionController::DeactivateSelection() { |
| DCHECK(start_selection_handle_); |
| DCHECK(end_selection_handle_); |
| LogSelectionEnd(); |
| + longpress_drag_selector_.OnSelectionDeactivated(); |
| start_selection_handle_->SetEnabled(false); |
| end_selection_handle_->SetEnabled(false); |
| is_selection_active_ = false; |
| @@ -469,6 +502,16 @@ void TouchSelectionController::ResetCachedValuesIfInactive() { |
| end_orientation_ = TouchHandleOrientation::UNDEFINED; |
| } |
| +void TouchSelectionController::RefreshHandleVisibility() { |
| + TouchHandle::AnimationStyle animation_style = GetAnimationStyle(true); |
| + if (is_selection_active_) { |
| + start_selection_handle_->SetVisible(GetStartVisible(), animation_style); |
| + end_selection_handle_->SetVisible(GetEndVisible(), animation_style); |
| + } |
| + if (is_insertion_active_) |
| + insertion_handle_->SetVisible(GetStartVisible(), animation_style); |
| +} |
| + |
| gfx::Vector2dF TouchSelectionController::GetStartLineOffset() const { |
| return ComputeLineOffsetFromBottom(start_); |
| } |
| @@ -478,11 +521,17 @@ gfx::Vector2dF TouchSelectionController::GetEndLineOffset() const { |
| } |
| bool TouchSelectionController::GetStartVisible() const { |
| - return start_.visible() && !temporarily_hidden_; |
| + if (!start_.visible()) |
| + return false; |
| + |
| + return !temporarily_hidden_ && !longpress_drag_selector_.IsDetectingDrag(); |
| } |
| bool TouchSelectionController::GetEndVisible() const { |
| - return end_.visible() && !temporarily_hidden_; |
| + if (!end_.visible()) |
| + return false; |
| + |
| + return !temporarily_hidden_ && !longpress_drag_selector_.IsDetectingDrag(); |
| } |
| TouchHandle::AnimationStyle TouchSelectionController::GetAnimationStyle( |