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

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

Issue 335943002: [Android] Composited selection handle rendering (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@input_native_handles_final
Patch Set: Fix animation tests Created 6 years, 5 months 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 } // namespace
21
22 // Responsible for rendering a selection or insertion handle for text editing.
23 TouchHandle::TouchHandle(TouchHandleClient* client,
24 TouchHandleOrientation orientation)
25 : drawable_(client->CreateDrawable()),
26 client_(client),
27 orientation_(orientation),
28 deferred_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
29 alpha_(0.f),
30 animate_deferred_fade_(false),
31 enabled_(true),
32 is_visible_(false),
33 is_dragging_(false) {
34 DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
35 drawable_->SetEnabled(enabled_);
36 drawable_->SetOrientation(orientation_);
37 drawable_->SetAlpha(alpha_);
38 drawable_->SetVisible(is_visible_);
39 drawable_->SetFocus(position_);
40 }
41
42 TouchHandle::~TouchHandle() {
43 }
44
45 void TouchHandle::SetEnabled(bool enabled) {
46 if (enabled_ == enabled)
47 return;
48 if (!enabled) {
49 EndDrag();
50 EndFade();
51 }
52 enabled_ = enabled;
53 drawable_->SetEnabled(enabled);
54 }
55
56 void TouchHandle::SetVisible(bool visible, AnimationStyle animation_style) {
57 DCHECK(enabled_);
58 if (is_visible_ == visible)
59 return;
60
61 is_visible_ = visible;
62
63 // Handle repositioning may have been deferred while previously invisible.
64 if (visible)
65 drawable_->SetFocus(position_);
66
67 bool animate = animation_style != ANIMATION_NONE;
68 if (is_dragging_) {
69 animate_deferred_fade_ = animate;
70 return;
71 }
72
73 if (animate)
74 BeginFade();
75 else
76 EndFade();
77 }
78
79 void TouchHandle::SetPosition(const gfx::PointF& position) {
80 DCHECK(enabled_);
81 if (position_ == position)
82 return;
83 position_ = position;
84 // Suppress repositioning a handle while invisible or fading out to prevent it
85 // from "ghosting" outside the visible bounds. The position will be pushed to
86 // the drawable when the handle regains visibility (see |SetVisible()|).
87 if (is_visible_)
88 drawable_->SetFocus(position_);
89 }
90
91 void TouchHandle::SetOrientation(TouchHandleOrientation orientation) {
92 DCHECK(enabled_);
93 DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
94 if (is_dragging_) {
95 deferred_orientation_ = orientation;
96 return;
97 }
98 DCHECK_EQ(deferred_orientation_, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
99 if (orientation_ == orientation)
100 return;
101
102 orientation_ = orientation;
103 drawable_->SetOrientation(orientation);
104 }
105
106 bool TouchHandle::WillHandleTouchEvent(const ui::MotionEvent& event) {
107 if (!enabled_)
108 return false;
109
110 if (!is_dragging_ && event.GetAction() != ui::MotionEvent::ACTION_DOWN)
111 return false;
112
113 switch (event.GetAction()) {
114 case ui::MotionEvent::ACTION_DOWN: {
115 gfx::PointF touch_position = gfx::PointF(event.GetX(), event.GetY());
116 if (!is_visible_ || !drawable_->ContainsPoint(touch_position))
117 return false;
118 touch_down_position_ = touch_position;
119 touch_to_focus_offset_ = position_ - touch_down_position_;
120 touch_down_time_ = event.GetEventTime();
121 BeginDrag();
122 } break;
123
124 case ui::MotionEvent::ACTION_MOVE: {
125 gfx::PointF new_position =
126 gfx::PointF(event.GetX(), event.GetY()) + touch_to_focus_offset_;
127 client_->OnHandleDragUpdate(*this, new_position);
128 } break;
129
130 case ui::MotionEvent::ACTION_UP: {
131 // TODO(jdduke): Use the platform touch slop distance and tap delay to
132 // properly detect a tap, crbug.com/394093.
133 base::TimeDelta delay = event.GetEventTime() - touch_down_time_;
134 if (delay < base::TimeDelta::FromMilliseconds(180))
135 client_->OnHandleTapped(*this);
136
137 EndDrag();
138 } break;
139
140 case ui::MotionEvent::ACTION_CANCEL:
141 EndDrag();
142 break;
143
144 default:
145 break;
146 };
147 return true;
148 }
149
150 bool TouchHandle::Animate(base::TimeTicks frame_time) {
151 if (fade_end_time_ == base::TimeTicks())
152 return false;
153
154 DCHECK(enabled_);
155
156 float time_u =
157 1.f - (fade_end_time_ - frame_time).InMillisecondsF() / kFadeDurationMs;
158 float position_u =
159 (position_ - fade_start_position_).LengthSquared() / kFadeDistanceSquared;
160 float u = std::max(time_u, position_u);
161 SetAlpha(is_visible_ ? u : 1.f - u);
162
163 if (u >= 1.f) {
164 EndFade();
165 return false;
166 }
167
168 return true;
169 }
170
171 void TouchHandle::BeginDrag() {
172 DCHECK(enabled_);
173 if (is_dragging_)
174 return;
175 EndFade();
176 is_dragging_ = true;
177 client_->OnHandleDragBegin(*this);
178 }
179
180 void TouchHandle::EndDrag() {
181 DCHECK(enabled_);
182 if (!is_dragging_)
183 return;
184
185 is_dragging_ = false;
186 client_->OnHandleDragEnd(*this);
187
188 if (deferred_orientation_ != TOUCH_HANDLE_ORIENTATION_UNDEFINED) {
189 TouchHandleOrientation deferred_orientation = deferred_orientation_;
190 deferred_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
191 SetOrientation(deferred_orientation);
192 }
193
194 if (animate_deferred_fade_) {
195 BeginFade();
196 } else {
197 // As drawable visibility assignment is deferred while dragging, push the
198 // change by forcing fade completion.
199 EndFade();
200 }
201 }
202
203 void TouchHandle::BeginFade() {
204 DCHECK(enabled_);
205 DCHECK(!is_dragging_);
206 animate_deferred_fade_ = false;
207 const float target_alpha = is_visible_ ? 1.f : 0.f;
208 if (target_alpha == alpha_) {
209 EndFade();
210 return;
211 }
212
213 drawable_->SetVisible(true);
214 fade_end_time_ = base::TimeTicks::Now() +
215 base::TimeDelta::FromMillisecondsD(
216 kFadeDurationMs * std::abs(target_alpha - alpha_));
217 fade_start_position_ = position_;
218 client_->SetNeedsAnimate();
219 }
220
221 void TouchHandle::EndFade() {
222 DCHECK(enabled_);
223 animate_deferred_fade_ = false;
224 fade_end_time_ = base::TimeTicks();
225 SetAlpha(is_visible_ ? 1.f : 0.f);
226 drawable_->SetVisible(is_visible_);
227 }
228
229 void TouchHandle::SetAlpha(float alpha) {
230 alpha = std::max(0.f, std::min(1.f, alpha));
231 if (alpha_ == alpha)
232 return;
233 alpha_ = alpha;
234 drawable_->SetAlpha(alpha);
235 }
236
237 } // 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