Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: content/browser/renderer_host/input/touch_handle.cc

Issue 759433002: Reland: Move TouchSelectionController from content to ui (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Excluded ui/touch_selection from Windows GN build Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/touch_handle.h"
6
7 #include <cmath>
8
9 namespace content {
10
11 namespace {
12
13 // Maximum duration of a fade sequence.
14 const double kFadeDurationMs = 200;
15
16 // Maximum amount of travel for a fade sequence. This avoids handle "ghosting"
17 // when the handle is moving rapidly while the fade is active.
18 const double kFadeDistanceSquared = 20.f * 20.f;
19
20 // Avoid using an empty touch rect, as it may fail the intersection test event
21 // if it lies within the other rect's bounds.
22 const float kMinTouchMajorForHitTesting = 1.f;
23
24 // The maximum touch size to use when computing whether a touch point is
25 // targetting a touch handle. This is necessary for devices that misreport
26 // touch radii, preventing inappropriately largely touch sizes from completely
27 // breaking handle dragging behavior.
28 const float kMaxTouchMajorForHitTesting = 36.f;
29
30 } // namespace
31
32 // Responsible for rendering a selection or insertion handle for text editing.
33 TouchHandle::TouchHandle(TouchHandleClient* client,
34 TouchHandleOrientation orientation)
35 : drawable_(client->CreateDrawable()),
36 client_(client),
37 orientation_(orientation),
38 deferred_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
39 alpha_(0.f),
40 animate_deferred_fade_(false),
41 enabled_(true),
42 is_visible_(false),
43 is_dragging_(false),
44 is_drag_within_tap_region_(false) {
45 DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
46 drawable_->SetEnabled(enabled_);
47 drawable_->SetOrientation(orientation_);
48 drawable_->SetAlpha(alpha_);
49 drawable_->SetFocus(position_);
50 }
51
52 TouchHandle::~TouchHandle() {
53 }
54
55 void TouchHandle::SetEnabled(bool enabled) {
56 if (enabled_ == enabled)
57 return;
58 if (!enabled) {
59 EndDrag();
60 EndFade();
61 }
62 enabled_ = enabled;
63 drawable_->SetEnabled(enabled);
64 }
65
66 void TouchHandle::SetVisible(bool visible, AnimationStyle animation_style) {
67 DCHECK(enabled_);
68 if (is_visible_ == visible)
69 return;
70
71 is_visible_ = visible;
72
73 // Handle repositioning may have been deferred while previously invisible.
74 if (visible)
75 drawable_->SetFocus(position_);
76
77 bool animate = animation_style != ANIMATION_NONE;
78 if (is_dragging_) {
79 animate_deferred_fade_ = animate;
80 return;
81 }
82
83 if (animate)
84 BeginFade();
85 else
86 EndFade();
87 }
88
89 void TouchHandle::SetPosition(const gfx::PointF& position) {
90 DCHECK(enabled_);
91 if (position_ == position)
92 return;
93 position_ = position;
94 // Suppress repositioning a handle while invisible or fading out to prevent it
95 // from "ghosting" outside the visible bounds. The position will be pushed to
96 // the drawable when the handle regains visibility (see |SetVisible()|).
97 if (is_visible_)
98 drawable_->SetFocus(position_);
99 }
100
101 void TouchHandle::SetOrientation(TouchHandleOrientation orientation) {
102 DCHECK(enabled_);
103 DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
104 if (is_dragging_) {
105 deferred_orientation_ = orientation;
106 return;
107 }
108 DCHECK_EQ(deferred_orientation_, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
109 if (orientation_ == orientation)
110 return;
111
112 orientation_ = orientation;
113 drawable_->SetOrientation(orientation);
114 }
115
116 bool TouchHandle::WillHandleTouchEvent(const ui::MotionEvent& event) {
117 if (!enabled_)
118 return false;
119
120 if (!is_dragging_ && event.GetAction() != ui::MotionEvent::ACTION_DOWN)
121 return false;
122
123 switch (event.GetAction()) {
124 case ui::MotionEvent::ACTION_DOWN: {
125 if (!is_visible_)
126 return false;
127 const float touch_size = std::max(
128 kMinTouchMajorForHitTesting,
129 std::min(kMaxTouchMajorForHitTesting, event.GetTouchMajor()));
130 const gfx::RectF touch_rect(event.GetX() - touch_size * .5f,
131 event.GetY() - touch_size * .5f,
132 touch_size,
133 touch_size);
134 if (!drawable_->IntersectsWith(touch_rect))
135 return false;
136 touch_down_position_ = gfx::PointF(event.GetX(), event.GetY());
137 touch_to_focus_offset_ = position_ - touch_down_position_;
138 touch_down_time_ = event.GetEventTime();
139 BeginDrag();
140 } break;
141
142 case ui::MotionEvent::ACTION_MOVE: {
143 gfx::PointF touch_move_position(event.GetX(), event.GetY());
144 if (is_drag_within_tap_region_) {
145 const float tap_slop = client_->GetTapSlop();
146 is_drag_within_tap_region_ =
147 (touch_move_position - touch_down_position_).LengthSquared() <
148 tap_slop * tap_slop;
149 }
150
151 // Note that we signal drag update even if we're inside the tap region,
152 // as there are cases where characters are narrower than the slop length.
153 client_->OnHandleDragUpdate(*this,
154 touch_move_position + touch_to_focus_offset_);
155 } break;
156
157 case ui::MotionEvent::ACTION_UP: {
158 if (is_drag_within_tap_region_ &&
159 (event.GetEventTime() - touch_down_time_) <
160 client_->GetTapTimeout()) {
161 client_->OnHandleTapped(*this);
162 }
163
164 EndDrag();
165 } break;
166
167 case ui::MotionEvent::ACTION_CANCEL:
168 EndDrag();
169 break;
170
171 default:
172 break;
173 };
174 return true;
175 }
176
177 bool TouchHandle::Animate(base::TimeTicks frame_time) {
178 if (fade_end_time_ == base::TimeTicks())
179 return false;
180
181 DCHECK(enabled_);
182
183 float time_u =
184 1.f - (fade_end_time_ - frame_time).InMillisecondsF() / kFadeDurationMs;
185 float position_u =
186 (position_ - fade_start_position_).LengthSquared() / kFadeDistanceSquared;
187 float u = std::max(time_u, position_u);
188 SetAlpha(is_visible_ ? u : 1.f - u);
189
190 if (u >= 1.f) {
191 EndFade();
192 return false;
193 }
194
195 return true;
196 }
197
198 void TouchHandle::BeginDrag() {
199 DCHECK(enabled_);
200 if (is_dragging_)
201 return;
202 EndFade();
203 is_dragging_ = true;
204 is_drag_within_tap_region_ = true;
205 client_->OnHandleDragBegin(*this);
206 }
207
208 void TouchHandle::EndDrag() {
209 DCHECK(enabled_);
210 if (!is_dragging_)
211 return;
212
213 is_dragging_ = false;
214 is_drag_within_tap_region_ = false;
215 client_->OnHandleDragEnd(*this);
216
217 if (deferred_orientation_ != TOUCH_HANDLE_ORIENTATION_UNDEFINED) {
218 TouchHandleOrientation deferred_orientation = deferred_orientation_;
219 deferred_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
220 SetOrientation(deferred_orientation);
221 }
222
223 if (animate_deferred_fade_) {
224 BeginFade();
225 } else {
226 // As drawable visibility assignment is deferred while dragging, push the
227 // change by forcing fade completion.
228 EndFade();
229 }
230 }
231
232 void TouchHandle::BeginFade() {
233 DCHECK(enabled_);
234 DCHECK(!is_dragging_);
235 animate_deferred_fade_ = false;
236 const float target_alpha = is_visible_ ? 1.f : 0.f;
237 if (target_alpha == alpha_) {
238 EndFade();
239 return;
240 }
241
242 fade_end_time_ = base::TimeTicks::Now() +
243 base::TimeDelta::FromMillisecondsD(
244 kFadeDurationMs * std::abs(target_alpha - alpha_));
245 fade_start_position_ = position_;
246 client_->SetNeedsAnimate();
247 }
248
249 void TouchHandle::EndFade() {
250 DCHECK(enabled_);
251 animate_deferred_fade_ = false;
252 fade_end_time_ = base::TimeTicks();
253 SetAlpha(is_visible_ ? 1.f : 0.f);
254 }
255
256 void TouchHandle::SetAlpha(float alpha) {
257 alpha = std::max(0.f, std::min(1.f, alpha));
258 if (alpha_ == alpha)
259 return;
260 alpha_ = alpha;
261 drawable_->SetAlpha(alpha);
262 }
263
264 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/input/touch_handle.h ('k') | content/browser/renderer_host/input/touch_handle_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698