Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / input / gesture_text_selector.cc
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_detector.h"
9 #include "ui/events/gesture_detection/gesture_provider_config_helper.h"
10 #include "ui/events/gesture_detection/motion_event.h"
11
12 using ui::GestureDetector;
13 using ui::MotionEvent;
14
15 namespace content {
16 namespace {
17 scoped_ptr<GestureDetector> CreateGestureDetector(
18     ui::GestureListener* listener) {
19   GestureDetector::Config config =
20       ui::DefaultGestureProviderConfig().gesture_detector_config;
21
22   ui::DoubleTapListener* null_double_tap_listener = nullptr;
23
24   // Doubletap, showpress and longpress detection are not required, and
25   // should be explicitly disabled for efficiency.
26   scoped_ptr<ui::GestureDetector> detector(
27       new ui::GestureDetector(config, listener, null_double_tap_listener));
28   detector->set_longpress_enabled(false);
29   detector->set_showpress_enabled(false);
30
31   return detector.Pass();
32 }
33
34 }  // namespace
35
36 GestureTextSelector::GestureTextSelector(GestureTextSelectorClient* client)
37     : client_(client),
38       text_selection_triggered_(false),
39       secondary_button_pressed_(false),
40       anchor_x_(0.0f),
41       anchor_y_(0.0f) {
42   DCHECK(client);
43 }
44
45 GestureTextSelector::~GestureTextSelector() {
46 }
47
48 bool GestureTextSelector::OnTouchEvent(const MotionEvent& event) {
49   if (event.GetAction() == MotionEvent::ACTION_DOWN) {
50     // Only trigger selection on ACTION_DOWN to prevent partial touch or gesture
51     // sequences from being forwarded.
52     text_selection_triggered_ = ShouldStartTextSelection(event);
53     secondary_button_pressed_ =
54         event.GetButtonState() == MotionEvent::BUTTON_SECONDARY;
55     anchor_x_ = event.GetX();
56     anchor_y_ = event.GetY();
57   }
58
59   if (!text_selection_triggered_)
60     return false;
61
62   if (event.GetAction() == MotionEvent::ACTION_MOVE) {
63     secondary_button_pressed_ =
64         event.GetButtonState() == MotionEvent::BUTTON_SECONDARY;
65     if (!secondary_button_pressed_) {
66       anchor_x_ = event.GetX();
67       anchor_y_ = event.GetY();
68     }
69   }
70
71   if (!gesture_detector_)
72     gesture_detector_ = CreateGestureDetector(this);
73
74   gesture_detector_->OnTouchEvent(event);
75
76   // Always return true, even if |gesture_detector_| technically doesn't
77   // consume the event, to prevent a partial touch stream from being forwarded.
78   return true;
79 }
80
81 bool GestureTextSelector::OnSingleTapUp(const MotionEvent& e) {
82   DCHECK(text_selection_triggered_);
83   client_->LongPress(e.GetEventTime(), e.GetX(), e.GetY());
84   return true;
85 }
86
87 bool GestureTextSelector::OnScroll(const MotionEvent& e1,
88                                    const MotionEvent& e2,
89                                    float distance_x,
90                                    float distance_y) {
91   DCHECK(text_selection_triggered_);
92
93   // Return if Stylus button is not pressed.
94   if (!secondary_button_pressed_)
95     return true;
96
97   // TODO(changwan): check if we can show handles after the scroll finishes
98   // instead. Currently it is not possible as ShowSelectionHandles should
99   // be called before we change the selection.
100   client_->ShowSelectionHandlesAutomatically();
101   client_->SelectRange(anchor_x_, anchor_y_, e2.GetX(), e2.GetY());
102   return true;
103 }
104
105 // static
106 bool GestureTextSelector::ShouldStartTextSelection(const MotionEvent& event) {
107   DCHECK_GT(event.GetPointerCount(), 0u);
108   // Currently we are supporting stylus-only cases.
109   const bool is_stylus = event.GetToolType(0) == MotionEvent::TOOL_TYPE_STYLUS;
110   const bool is_only_secondary_button_pressed =
111       event.GetButtonState() == MotionEvent::BUTTON_SECONDARY;
112   return is_stylus && is_only_secondary_button_pressed;
113 }
114
115 }  // namespace content