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. 4 5 #include "content/browser/renderer_host/input/gesture_text_selector.h" 6 7 #include "ui/events/event_constants.h" 8 #include "ui/events/gesture_detection/gesture_event_data.h" 9 #include "ui/events/gesture_detection/motion_event.h" 10 11 namespace content { 12 13 GestureTextSelector::GestureTextSelector(GestureTextSelectorClient* client) 14 : client_(client), 15 text_selection_triggered_(false), 16 anchor_x_(0.0f), 17 anchor_y_(0.0f) { 18 } 19 20 GestureTextSelector::~GestureTextSelector() { 21 } 22 23 bool GestureTextSelector::OnTouchEvent(const ui::MotionEvent& event) { 24 if (event.GetAction() == ui::MotionEvent::ACTION_DOWN) { 25 // Only trigger selection on ACTION_DOWN to prevent partial touch or gesture 26 // sequences from being forwarded. 27 text_selection_triggered_ = ShouldStartTextSelection(event); 28 } 29 return text_selection_triggered_; 30 } 31 32 bool GestureTextSelector::OnGestureEvent(const ui::GestureEventData& gesture) { 33 if (!text_selection_triggered_) 34 return false; 35 36 switch (gesture.type()) { 37 case ui::ET_GESTURE_TAP: { 38 client_->LongPress(gesture.time, gesture.x, gesture.y); 39 break; 40 } 41 case ui::ET_GESTURE_SCROLL_BEGIN: { 42 client_->Unselect(); 43 anchor_x_ = gesture.x; 44 anchor_y_ = gesture.y; 45 break; 46 } 47 case ui::ET_GESTURE_SCROLL_UPDATE: { 48 // TODO(changwan): check if we can show handles on ET_GESTURE_SCROLL_END 49 // instead. Currently it is not possible as ShowSelectionHandles should 50 // be called before we change the selection. 51 client_->ShowSelectionHandlesAutomatically(); 52 client_->SelectRange(anchor_x_, anchor_y_, gesture.x, gesture.y); 53 break; 54 } 55 default: 56 // Suppress all other gestures when we are selecting text. 57 break; 58 } 59 return true; 60 } 61 62 // static 63 bool GestureTextSelector::ShouldStartTextSelection( 64 const ui::MotionEvent& event) { 65 DCHECK_GT(event.GetPointerCount(), 0u); 66 // Currently we are supporting stylus-only cases. 67 const bool is_stylus = 68 event.GetToolType(0) == ui::MotionEvent::TOOL_TYPE_STYLUS; 69 const bool is_only_secondary_button_pressed = 70 event.GetButtonState() == ui::MotionEvent::BUTTON_SECONDARY; 71 return is_stylus && is_only_secondary_button_pressed; 72 } 73 74 } // namespace content 75