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

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: Rebase 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 enabled_(true),
29 is_visible_(false),
30 is_dragging_(false) {
31 DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
32 drawable_->SetEnabled(enabled_);
33 drawable_->SetOrientation(orientation_);
34 drawable_->SetAlpha(alpha_);
35 drawable_->SetVisible(is_visible_);
36 drawable_->SetFocus(position_);
37 }
38
39 TouchHandle::~TouchHandle() {
40 }
41
42 void TouchHandle::SetEnabled(bool enabled) {
43 if (enabled_ == enabled)
44 return;
45 enabled_ = enabled;
46 drawable_->SetEnabled(enabled);
47 if (!enabled_) {
48 EndFade();
cjhopman 2014/07/14 18:23:52 I think that, since EndDrag() can trigger a fade,
jdduke (slow) 2014/07/15 15:44:24 You're absolutely right, I've been running tests l
49 EndDrag();
50 }
51 }
52
53 void TouchHandle::SetVisible(bool visible, AnimationStyle animation_style) {
54 if (is_visible_ == visible)
55 return;
56 is_visible_ = visible;
57 if (!enabled_ || animation_style == ANIMATION_NONE) {
58 EndFade();
59 } else {
60 // The fade will be rescheduled once dragging completes.
61 if (!is_dragging_)
62 BeginFade();
63 }
64 }
65
66 void TouchHandle::SetPosition(const gfx::PointF& position) {
67 if (position_ == position)
68 return;
69 position_ = position;
70 // Suppress repositioning a handle while invisible or fading to prevent it
71 // from "ghosting" outside the visible bounds. The position will be pushed to
72 // the drawable when the handle regains visibility (see |{Begin|End}Fade|).
cjhopman 2014/07/14 18:23:52 For handling the deferred position while invisible
jdduke (slow) 2014/07/15 15:44:24 That would be a better place, but we still need th
73 if (is_visible_)
cjhopman 2014/07/14 18:23:52 This allows changing the position while fading in
jdduke (slow) 2014/07/15 15:44:24 Hmm, yeah we only want to defer while fading *out*
74 drawable_->SetFocus(position_);
75 }
76
77 void TouchHandle::SetOrientation(TouchHandleOrientation orientation) {
78 DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
79 if (is_dragging_) {
80 deferred_orientation_ = orientation;
81 return;
82 }
83 deferred_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
84 if (orientation_ == orientation)
85 return;
86
87 orientation_ = orientation;
88 drawable_->SetOrientation(orientation);
89 }
90
91 bool TouchHandle::WillHandleTouchEvent(const ui::MotionEvent& event) {
92 if (!enabled_)
93 return false;
94
95 if (!is_dragging_ && event.GetAction() != ui::MotionEvent::ACTION_DOWN)
96 return false;
97
98 switch (event.GetAction()) {
99 case ui::MotionEvent::ACTION_DOWN: {
100 gfx::PointF touch_position = gfx::PointF(event.GetX(), event.GetY());
101 if (!is_visible_ || !drawable_->ContainsPoint(touch_position))
102 return false;
103 touch_down_position_ = touch_position;
104 touch_to_focus_offset_ = position_ - touch_down_position_;
105 touch_down_time_ = event.GetEventTime();
106 BeginDrag();
107 } break;
108
109 case ui::MotionEvent::ACTION_MOVE: {
110 gfx::PointF new_position =
111 gfx::PointF(event.GetX(), event.GetY()) + touch_to_focus_offset_;
112 client_->OnHandleDragUpdate(*this, new_position);
113 } break;
114
115 case ui::MotionEvent::ACTION_UP: {
116 base::TimeDelta delay = event.GetEventTime() - touch_down_time_;
117 if (delay < base::TimeDelta::FromMilliseconds(180))
118 client_->OnHandleTapped(*this);
119
120 EndDrag();
121 } break;
122
123 case ui::MotionEvent::ACTION_CANCEL:
124 EndDrag();
125 break;
126
127 default:
128 break;
129 };
130 return true;
131 }
132
133 bool TouchHandle::Animate(base::TimeTicks frame_time) {
134 if (fade_end_time_ == base::TimeTicks())
135 return false;
136
137 float time_u =
138 1.f - (fade_end_time_ - frame_time).InMillisecondsF() / kFadeDurationMs;
139 float position_u =
140 (position_ - fade_start_position_).LengthSquared() / kFadeDistanceSquared;
141 float u = std::max(time_u, position_u);
142 SetAlpha(is_visible_ ? u : 1.f - u);
143
144 if (u >= 1.f) {
145 EndFade();
146 return false;
147 }
148
149 return true;
150 }
151
152 void TouchHandle::BeginDrag() {
153 DCHECK(enabled_);
154 if (is_dragging_)
155 return;
156 is_dragging_ = true;
157 client_->OnHandleDragBegin(*this);
158 }
159
160 void TouchHandle::EndDrag() {
161 if (!is_dragging_)
162 return;
163
164 is_dragging_ = false;
165 client_->OnHandleDragEnd(*this);
166
167 if (deferred_orientation_ != TOUCH_HANDLE_ORIENTATION_UNDEFINED)
168 SetOrientation(deferred_orientation_);
169
170 BeginFade();
171 }
172
173 void TouchHandle::BeginFade() {
174 DCHECK(enabled_);
175
176 if (is_visible_)
177 drawable_->SetFocus(position_);
178
179 const float target_alpha = is_visible_ ? 1.f : 0.f;
180 if (target_alpha == alpha_)
181 return;
182
183 drawable_->SetVisible(true);
184 fade_end_time_ = base::TimeTicks::Now() +
185 base::TimeDelta::FromMillisecondsD(
186 kFadeDurationMs * std::abs(target_alpha - alpha_));
187 fade_start_position_ = position_;
188 client_->SetNeedsAnimate();
189 }
190
191 void TouchHandle::EndFade() {
192 if (is_visible_)
193 drawable_->SetFocus(position_);
194
195 fade_end_time_ = base::TimeTicks();
196 SetAlpha(is_visible_ ? 1.f : 0.f);
197 drawable_->SetVisible(is_visible_);
198 }
199
200 void TouchHandle::SetAlpha(float alpha) {
201 alpha = std::max(0.f, std::min(1.f, alpha));
202 if (alpha_ == alpha)
203 return;
204 alpha_ = alpha;
205 drawable_->SetAlpha(alpha);
206 }
207
208 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698