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

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: Tweaks to dragging and visibility 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 if (is_visible_ == visible)
56 return;
57
58 is_visible_ = visible;
59
60 // Handle repositioning may have been deferred while previously invisible.
61 if (visible)
62 drawable_->SetFocus(position_);
63
64 bool animate = animation_style != ANIMATION_NONE;
65 if (is_dragging_) {
66 animate_deferred_fade_ = animate;
67 return;
68 }
69
70 if (enabled_ && animate)
71 BeginFade();
72 else
73 EndFade();
74 }
75
76 void TouchHandle::SetPosition(const gfx::PointF& position) {
77 if (position_ == position)
78 return;
79 position_ = position;
80 // Suppress repositioning a handle while invisible or fading out to prevent it
81 // from "ghosting" outside the visible bounds. The position will be pushed to
82 // the drawable when the handle regains visibility (see |SetVisible()|).
83 if (is_visible_)
84 drawable_->SetFocus(position_);
85 }
86
87 void TouchHandle::SetOrientation(TouchHandleOrientation orientation) {
88 DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
89 if (is_dragging_) {
90 deferred_orientation_ = orientation;
91 return;
92 }
93 deferred_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
cjhopman 2014/07/15 18:40:28 If you reset deferred_orientation in whatever call
jdduke (slow) 2014/07/15 21:51:56 Done.
94 if (orientation_ == orientation)
95 return;
96
97 orientation_ = orientation;
98 drawable_->SetOrientation(orientation);
99 }
100
101 bool TouchHandle::WillHandleTouchEvent(const ui::MotionEvent& event) {
102 if (!enabled_)
103 return false;
104
105 if (!is_dragging_ && event.GetAction() != ui::MotionEvent::ACTION_DOWN)
106 return false;
107
108 switch (event.GetAction()) {
109 case ui::MotionEvent::ACTION_DOWN: {
110 gfx::PointF touch_position = gfx::PointF(event.GetX(), event.GetY());
111 if (!is_visible_ || !drawable_->ContainsPoint(touch_position))
112 return false;
113 touch_down_position_ = touch_position;
114 touch_to_focus_offset_ = position_ - touch_down_position_;
115 touch_down_time_ = event.GetEventTime();
116 BeginDrag();
cjhopman 2014/07/15 18:40:28 The handle could be fading in at this point. It's
jdduke (slow) 2014/07/15 21:51:56 Done.
117 } break;
118
119 case ui::MotionEvent::ACTION_MOVE: {
120 gfx::PointF new_position =
121 gfx::PointF(event.GetX(), event.GetY()) + touch_to_focus_offset_;
122 client_->OnHandleDragUpdate(*this, new_position);
123 } break;
124
125 case ui::MotionEvent::ACTION_UP: {
126 base::TimeDelta delay = event.GetEventTime() - touch_down_time_;
127 if (delay < base::TimeDelta::FromMilliseconds(180))
cjhopman 2014/07/15 18:40:28 Should we delay dragging during this period? Delay
jdduke (slow) 2014/07/15 21:51:56 Well, we really ought to be using a proper touch s
128 client_->OnHandleTapped(*this);
129
130 EndDrag();
131 } break;
132
133 case ui::MotionEvent::ACTION_CANCEL:
134 EndDrag();
135 break;
136
137 default:
138 break;
139 };
140 return true;
141 }
142
143 bool TouchHandle::Animate(base::TimeTicks frame_time) {
144 if (fade_end_time_ == base::TimeTicks())
145 return false;
146
147 float time_u =
148 1.f - (fade_end_time_ - frame_time).InMillisecondsF() / kFadeDurationMs;
149 float position_u =
150 (position_ - fade_start_position_).LengthSquared() / kFadeDistanceSquared;
151 float u = std::max(time_u, position_u);
152 SetAlpha(is_visible_ ? u : 1.f - u);
153
154 if (u >= 1.f) {
155 EndFade();
156 return false;
157 }
158
159 return true;
160 }
161
162 void TouchHandle::BeginDrag() {
163 DCHECK(enabled_);
164 if (is_dragging_)
165 return;
166 is_dragging_ = true;
167 client_->OnHandleDragBegin(*this);
168 }
169
170 void TouchHandle::EndDrag() {
171 if (!is_dragging_)
172 return;
173
174 is_dragging_ = false;
175 client_->OnHandleDragEnd(*this);
176
177 if (deferred_orientation_ != TOUCH_HANDLE_ORIENTATION_UNDEFINED)
178 SetOrientation(deferred_orientation_);
179
180 // As a fade may have been deferred while dragging, trigger now if necessary.
181 if (enabled_ && animate_deferred_fade_)
182 BeginFade();
183 else
184 EndFade();
185 }
186
187 void TouchHandle::BeginFade() {
188 DCHECK(enabled_);
189 animate_deferred_fade_ = false;
190 const float target_alpha = is_visible_ ? 1.f : 0.f;
191 if (target_alpha == alpha_)
cjhopman 2014/07/15 18:40:28 If the handle is visible and I do fade out immedia
jdduke (slow) 2014/07/15 21:51:56 I'll terminate the fade here if (target_alpha == a
192 return;
193
194 drawable_->SetVisible(true);
195 fade_end_time_ = base::TimeTicks::Now() +
196 base::TimeDelta::FromMillisecondsD(
197 kFadeDurationMs * std::abs(target_alpha - alpha_));
cjhopman 2014/07/15 18:40:28 If i fade out a handle, then reposition it, then f
jdduke (slow) 2014/07/15 21:51:56 Hmm, preserving the fade alpha is somewhat desirab
198 fade_start_position_ = position_;
199 client_->SetNeedsAnimate();
200 }
201
202 void TouchHandle::EndFade() {
203 animate_deferred_fade_ = false;
204 fade_end_time_ = base::TimeTicks();
205 SetAlpha(is_visible_ ? 1.f : 0.f);
206 drawable_->SetVisible(is_visible_);
207 }
208
209 void TouchHandle::SetAlpha(float alpha) {
210 alpha = std::max(0.f, std::min(1.f, alpha));
211 if (alpha_ == alpha)
212 return;
213 alpha_ = alpha;
214 drawable_->SetAlpha(alpha);
215 }
216
217 } // 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