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

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: Test and comments 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 is_visible_(false),
29 is_dragging_(false) {
30 DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
31 drawable_->SetOrientation(orientation_);
32 drawable_->SetAlpha(alpha_);
33 drawable_->SetVisible(is_visible_);
34 }
35
36 TouchHandle::~TouchHandle() {
37 }
38
39 void TouchHandle::SetVisible(bool visible) {
40 if (is_visible_ == visible)
41 return;
42 is_visible_ = visible;
43 drawable_->SetVisible(visible);
44 CancelFade();
45 }
46
47 void TouchHandle::SetVisibleAnimated(bool visible) {
48 if (is_visible_ == visible)
49 return;
50 is_visible_ = visible;
51 // The fade will be reschedule once dragging completes.
52 if (is_dragging_)
53 return;
54 ScheduleFade();
55 }
56
57 void TouchHandle::SetPosition(const gfx::PointF& position) {
58 if (position_ == position)
59 return;
60 position_ = position;
61 // Avoid positioning handles outside their visible bounds during a fade.
62 if (!fade_end_time_.is_null() && !is_visible_)
63 return;
64 drawable_->SetFocus(position_);
65 }
66
67 void TouchHandle::SetOrientation(TouchHandleOrientation orientation) {
68 DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
69 if (is_dragging_) {
70 deferred_orientation_ = orientation;
71 return;
72 }
73
74 deferred_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
75
76 if (orientation_ == orientation)
77 return;
78
79 orientation_ = orientation;
80 drawable_->SetOrientation(orientation);
81 }
82
83 void TouchHandle::Hide() {
84 SetVisible(false);
85 CancelFade();
86 is_dragging_ = false;
87 }
88
89 bool TouchHandle::WillHandleTouchEvent(const ui::MotionEvent& event) {
90 if (!is_dragging_ && event.GetAction() != ui::MotionEvent::ACTION_DOWN)
91 return false;
92
93 switch (event.GetAction()) {
94 case ui::MotionEvent::ACTION_DOWN: {
95 gfx::PointF touch_position = gfx::PointF(event.GetX(), event.GetY());
96 if (!is_visible_ || !drawable_->ContainsPoint(touch_position))
97 return false;
98 down_position_ = touch_position;
99 touch_to_focus_offset_ = position_ - down_position_;
100 touch_timer_ = event.GetEventTime();
101 BeginDrag();
102 } break;
103
104 case ui::MotionEvent::ACTION_MOVE: {
105 gfx::PointF new_position =
106 gfx::PointF(event.GetX(), event.GetY()) + touch_to_focus_offset_;
107 client_->OnHandleDragUpdate(*this, new_position);
108 } break;
109
110 case ui::MotionEvent::ACTION_UP: {
111 base::TimeDelta delay = event.GetEventTime() - touch_timer_;
112 if (delay < base::TimeDelta::FromMilliseconds(180))
113 client_->OnHandleTapped(*this);
114
115 EndDrag();
116 } break;
117
118 case ui::MotionEvent::ACTION_CANCEL:
119 EndDrag();
120 break;
121
122 default:
123 break;
124 };
125 return true;
126 }
127
128 bool TouchHandle::Animate(base::TimeTicks frame_time) {
129 if (fade_end_time_ == base::TimeTicks())
130 return false;
131
132 float time_u =
133 1.f - (fade_end_time_ - frame_time).InMillisecondsF() / kFadeDurationMs;
134 float position_u =
135 (position_ - fade_start_position_).LengthSquared() / kFadeDistanceSquared;
136 float u = std::max(time_u, position_u);
137 SetAlpha(is_visible_ ? u : 1.f - u);
138
139 if (u >= 1.f) {
140 CancelFade();
141 return false;
142 }
143
144 return true;
145 }
146
147 void TouchHandle::BeginDrag() {
148 if (is_dragging_)
149 return;
150 is_dragging_ = true;
151 client_->OnHandleDragBegin(*this);
152 }
153
154 void TouchHandle::EndDrag() {
155 if (!is_dragging_)
156 return;
157
158 is_dragging_ = false;
159 client_->OnHandleDragEnd(*this);
160
161 if (deferred_orientation_ != TOUCH_HANDLE_ORIENTATION_UNDEFINED)
162 SetOrientation(deferred_orientation_);
163
164 ScheduleFade();
165 }
166
167 void TouchHandle::ScheduleFade() {
168 const float target_alpha = is_visible_ ? 1.f : 0.f;
169 if (target_alpha == alpha_)
170 return;
171
172 drawable_->SetVisible(true);
173 fade_end_time_ = base::TimeTicks::Now() +
174 base::TimeDelta::FromMillisecondsD(
175 kFadeDurationMs * std::abs(target_alpha - alpha_));
176 fade_start_position_ = position_;
177 client_->SetNeedsAnimate();
178 }
179
180 void TouchHandle::CancelFade() {
181 fade_end_time_ = base::TimeTicks();
182 SetAlpha(is_visible_ ? 1.f : 0.f);
183 drawable_->SetVisible(is_visible_);
cjhopman 2014/07/07 22:13:40 Should this call drawable_->SetFocus(position_)? W
jdduke (slow) 2014/07/08 00:54:44 Yeah, may not matter but probably best for consist
184 }
185
186 void TouchHandle::SetAlpha(float alpha) {
187 alpha = std::max(0.f, std::min(1.f, alpha));
188 if (alpha_ == alpha)
189 return;
190 alpha_ = alpha;
191 drawable_->SetAlpha(alpha);
192 }
193
194 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698