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

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

Powered by Google App Engine
This is Rietveld 408576698