Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / browser / renderer_host / input / stylus_text_selector.cc
blob39315cc006d585ba78c15cced1445ad4431169ce
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 "content/browser/renderer_host/input/stylus_text_selector.h"
7 #include "ui/events/event_constants.h"
8 #include "ui/events/gesture_detection/gesture_detector.h"
9 #include "ui/events/gesture_detection/gesture_provider_config_helper.h"
10 #include "ui/events/gesture_detection/motion_event.h"
12 using ui::GestureDetector;
13 using ui::MotionEvent;
15 namespace content {
16 namespace {
17 scoped_ptr<GestureDetector> CreateGestureDetector(
18 ui::GestureListener* listener) {
19 GestureDetector::Config config =
20 ui::GetGestureProviderConfig(
21 ui::GestureProviderConfigType::CURRENT_PLATFORM)
22 .gesture_detector_config;
24 ui::DoubleTapListener* null_double_tap_listener = nullptr;
26 // Doubletap, showpress and longpress detection are not required, and
27 // should be explicitly disabled for efficiency.
28 scoped_ptr<ui::GestureDetector> detector(
29 new ui::GestureDetector(config, listener, null_double_tap_listener));
30 detector->set_longpress_enabled(false);
31 detector->set_showpress_enabled(false);
33 return detector.Pass();
36 } // namespace
38 StylusTextSelector::StylusTextSelector(StylusTextSelectorClient* client)
39 : client_(client),
40 text_selection_triggered_(false),
41 secondary_button_pressed_(false),
42 dragging_(false),
43 dragged_(false),
44 anchor_x_(0.0f),
45 anchor_y_(0.0f) {
46 DCHECK(client);
49 StylusTextSelector::~StylusTextSelector() {
52 bool StylusTextSelector::OnTouchEvent(const MotionEvent& event) {
53 // Only trigger selection on ACTION_DOWN to prevent partial touch or gesture
54 // sequences from being forwarded.
55 if (event.GetAction() == MotionEvent::ACTION_DOWN)
56 text_selection_triggered_ = ShouldStartTextSelection(event);
58 if (!text_selection_triggered_)
59 return false;
61 secondary_button_pressed_ =
62 event.GetButtonState() == MotionEvent::BUTTON_SECONDARY;
64 switch (event.GetAction()) {
65 case MotionEvent::ACTION_DOWN:
66 dragging_ = false;
67 dragged_ = false;
68 anchor_x_ = event.GetX();
69 anchor_y_ = event.GetY();
70 break;
72 case MotionEvent::ACTION_MOVE:
73 if (!secondary_button_pressed_) {
74 dragging_ = false;
75 anchor_x_ = event.GetX();
76 anchor_y_ = event.GetY();
78 break;
80 case MotionEvent::ACTION_UP:
81 case MotionEvent::ACTION_CANCEL:
82 if (dragged_)
83 client_->OnStylusSelectEnd();
84 dragged_ = false;
85 dragging_ = false;
86 break;
88 case MotionEvent::ACTION_POINTER_UP:
89 case MotionEvent::ACTION_POINTER_DOWN:
90 break;
91 case MotionEvent::ACTION_NONE:
92 NOTREACHED();
93 break;
96 if (!gesture_detector_)
97 gesture_detector_ = CreateGestureDetector(this);
99 gesture_detector_->OnTouchEvent(event);
101 // Always return true, even if |gesture_detector_| technically doesn't
102 // consume the event. This prevents forwarding of a partial touch stream.
103 return true;
106 bool StylusTextSelector::OnSingleTapUp(const MotionEvent& e) {
107 DCHECK(text_selection_triggered_);
108 DCHECK(!dragging_);
109 client_->OnStylusSelectTap(e.GetEventTime(), e.GetX(), e.GetY());
110 return true;
113 bool StylusTextSelector::OnScroll(const MotionEvent& e1,
114 const MotionEvent& e2,
115 float distance_x,
116 float distance_y) {
117 DCHECK(text_selection_triggered_);
119 // Return if Stylus button is not pressed.
120 if (!secondary_button_pressed_)
121 return true;
123 if (!dragging_) {
124 dragging_ = true;
125 dragged_ = true;
126 client_->OnStylusSelectBegin(anchor_x_, anchor_y_, e2.GetX(), e2.GetY());
127 } else {
128 client_->OnStylusSelectUpdate(e2.GetX(), e2.GetY());
131 return true;
134 // static
135 bool StylusTextSelector::ShouldStartTextSelection(const MotionEvent& event) {
136 DCHECK_GT(event.GetPointerCount(), 0u);
137 // Currently we are supporting stylus-only cases.
138 const bool is_stylus = event.GetToolType(0) == MotionEvent::TOOL_TYPE_STYLUS;
139 const bool is_only_secondary_button_pressed =
140 event.GetButtonState() == MotionEvent::BUTTON_SECONDARY;
141 return is_stylus && is_only_secondary_button_pressed;
144 } // namespace content