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

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

Issue 335943002: [Android] Composited selection handle rendering (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@input_native_handles_final
Patch Set: Clean up paste popup interaction 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_selection_controller.h"
6
7 #include "base/logging.h"
8 #include "third_party/WebKit/public/web/WebInputEvent.h"
9
10 namespace content {
11
12 TouchSelectionController::TouchSelectionController(
13 TouchSelectionControllerClient* client)
14 : client_(client),
15 start_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
16 start_visible_(false),
17 end_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
18 end_visible_(false),
19 is_insertion_active_(false),
20 allow_automatic_insertion_activation_(false),
21 is_selection_active_(false),
22 allow_automatic_selection_activation_(false),
23 selection_editable_(false),
24 selection_editable_for_last_update_(false) {
25 DCHECK(client_);
26 HideAndDisallowAutomaticShowing();
27 }
28
29 TouchSelectionController::~TouchSelectionController() {
30 }
31
32 void TouchSelectionController::OnSelectionBoundsChanged(
33 const gfx::RectF& start_rect,
34 TouchHandleOrientation start_orientation,
35 bool start_visible,
36 const gfx::RectF& end_rect,
37 TouchHandleOrientation end_orientation,
38 bool end_visible) {
39 if (!allow_automatic_selection_activation_ &&
40 !allow_automatic_insertion_activation_)
41 return;
42
43 if (start_rect_ == start_rect && end_rect_ == end_rect &&
44 start_orientation_ == start_orientation &&
45 end_orientation_ == end_orientation &&
46 start_visible_ == start_visible && end_visible_ == end_visible &&
47 selection_editable_ == selection_editable_for_last_update_)
48 return;
49
50 start_rect_ = start_rect;
51 start_orientation_ = start_orientation;
52 start_visible_ = start_visible;
53 end_rect_ = end_rect;
54 end_orientation_ = end_orientation;
55 end_visible_ = end_visible;
56 selection_editable_for_last_update_ = selection_editable_;
57
58 const bool is_selection_dragging =
59 is_selection_active_ && (start_selection_handle_->is_dragging() ||
60 end_selection_handle_->is_dragging());
61
62 // It's possible that the bounds temporarily overlap while a selection handle
63 // is being dragged, incorrectly reporting a CENTER orientation.
cjhopman 2014/07/09 22:29:12 Is it possible that I could have selection and the
jdduke (slow) 2014/07/10 02:08:39 Hmm, you're quite right... perhaps we require that
64 if (is_selection_dragging) {
65 if (start_orientation_ == TOUCH_HANDLE_CENTER)
66 start_orientation_ = start_selection_handle_->orientation();
67 if (end_orientation_ == TOUCH_HANDLE_CENTER)
68 end_orientation_ = end_selection_handle_->orientation();
69 }
70
71 const gfx::PointF start = GetStartPosition();
72 const gfx::PointF end = GetEndPosition();
73 if (start != end || is_selection_dragging) {
74 OnSelectionChanged();
75 return;
76 }
77
78 if (start_orientation_ == TOUCH_HANDLE_CENTER) {
79 OnInsertionChanged();
80 return;
81 }
82
83 HideAndDisallowAutomaticShowing();
84 }
85
86 bool TouchSelectionController::WillHandleTouchEvent(
87 const ui::MotionEvent& event) {
88 if (is_insertion_active_) {
89 DCHECK(insertion_handle_);
90 return insertion_handle_->WillHandleTouchEvent(event);
91 }
92
93 if (is_selection_active_) {
94 DCHECK(start_selection_handle_);
95 DCHECK(end_selection_handle_);
96 return start_selection_handle_->WillHandleTouchEvent(event) ||
97 end_selection_handle_->WillHandleTouchEvent(event);
98 }
99
100 return false;
101 }
102
103 void TouchSelectionController::AllowAutomaticInsertionShowing() {
104 if (allow_automatic_insertion_activation_)
105 return;
106 allow_automatic_insertion_activation_ = true;
107 if (!is_insertion_active_ && !is_selection_active_)
108 ResetCachedValues();
109 }
110
111 void TouchSelectionController::AllowAutomaticSelectionShowing() {
112 if (allow_automatic_selection_activation_)
113 return;
114 allow_automatic_selection_activation_ = true;
115 if (!is_insertion_active_ && !is_selection_active_)
116 ResetCachedValues();
117 }
118
119 void TouchSelectionController::HideAndDisallowAutomaticShowing() {
120 DeactivateInsertion();
121 DeactivateSelection();
122 allow_automatic_insertion_activation_ = false;
123 allow_automatic_selection_activation_ = false;
124 }
125
126 void TouchSelectionController::OnSelectionEditable(bool editable) {
127 if (selection_editable_ == editable)
128 return;
129 selection_editable_ = editable;
130 if (!selection_editable_)
131 DeactivateInsertion();
132 }
133
134 bool TouchSelectionController::Animate(base::TimeTicks frame_time) {
135 if (is_insertion_active_)
136 return insertion_handle_->Animate(frame_time);
137
138 if (is_selection_active_) {
139 bool needs_animate = start_selection_handle_->Animate(frame_time);
140 needs_animate |= end_selection_handle_->Animate(frame_time);
141 return needs_animate;
142 }
143
144 return false;
145 }
146
147 void TouchSelectionController::OnHandleDragBegin(const TouchHandle& handle) {
148 if (&handle == insertion_handle_.get())
149 return;
150
151 if (&handle == start_selection_handle_.get()) {
152 fixed_handle_position_ = end_selection_handle_->position() -
153 gfx::Vector2dF(0, GetEndLineHeight() / 2.f);
154 } else {
155 fixed_handle_position_ = start_selection_handle_->position() -
156 gfx::Vector2dF(0, GetStartLineHeight() / 2.f);
157 }
158 }
159
160 void TouchSelectionController::OnHandleDragUpdate(const TouchHandle& handle,
161 const gfx::PointF& position) {
162 // As the position corresponds to the bottom left point of the selection
163 // bound, offset it by half the corresponding line height.
164 float half_line_height = &handle == end_selection_handle_.get()
165 ? GetEndLineHeight() / 2.f
166 : GetStartLineHeight() / 2.f;
167 gfx::PointF line_position = position - gfx::Vector2dF(0, half_line_height);
168 if (&handle == insertion_handle_.get()) {
169 client_->MoveCaret(line_position);
170 } else {
171 client_->SelectBetweenCoordinates(fixed_handle_position_, line_position);
172 }
173 }
174
175 void TouchSelectionController::OnHandleDragEnd(const TouchHandle& handle) {
176 }
177
178 void TouchSelectionController::OnHandleTapped(const TouchHandle& handle) {
179 if (insertion_handle_ && &handle == insertion_handle_.get())
180 client_->OnSelectionEvent(INSERTION_TAPPED, GetStartPosition());
181 }
182
183 void TouchSelectionController::SetNeedsAnimate() {
184 client_->SetNeedsAnimate();
185 }
186
187 scoped_ptr<TouchHandleDrawable> TouchSelectionController::CreateDrawable() {
188 return client_->CreateDrawable();
189 }
190
191 void TouchSelectionController::OnInsertionChanged() {
192 DeactivateSelection();
193
194 if (!allow_automatic_insertion_activation_ || !selection_editable_)
195 return;
196
197 bool was_active = is_insertion_active_;
198 gfx::PointF position = GetStartPosition();
199 if (!was_active)
200 ActivateInsertion();
201 else
202 client_->OnSelectionEvent(INSERTION_MOVED, position);
203
204 insertion_handle_->SetVisible(
205 start_visible_,
206 was_active ? TouchHandle::ANIMATION_SMOOTH : TouchHandle::ANIMATION_NONE);
207
208 insertion_handle_->SetPosition(position);
209 }
210
211 void TouchSelectionController::OnSelectionChanged() {
212 DeactivateInsertion();
213
214 if (!allow_automatic_selection_activation_)
215 return;
216
217 const bool was_active = is_selection_active_;
218 ActivateSelection();
219
220 const TouchHandle::AnimationStyle animation =
221 was_active ? TouchHandle::ANIMATION_SMOOTH : TouchHandle::ANIMATION_NONE;
222 start_selection_handle_->SetVisible(start_visible_, animation);
223 end_selection_handle_->SetVisible(end_visible_, animation);
224
225 start_selection_handle_->SetPosition(GetStartPosition());
226 end_selection_handle_->SetPosition(GetEndPosition());
227 }
228
229 void TouchSelectionController::ActivateInsertion() {
230 DCHECK(!is_selection_active_);
231
232 if (!insertion_handle_)
233 insertion_handle_.reset(new TouchHandle(this, TOUCH_HANDLE_CENTER));
234
235 if (!is_insertion_active_) {
236 is_insertion_active_ = true;
237 client_->OnSelectionEvent(INSERTION_SHOWN, GetStartPosition());
238 }
239 }
240
241 void TouchSelectionController::DeactivateInsertion() {
242 if (!is_insertion_active_)
243 return;
244 DCHECK(insertion_handle_);
245 insertion_handle_->Hide();
246 is_insertion_active_ = false;
247 client_->OnSelectionEvent(INSERTION_CLEARED, gfx::PointF());
248 }
249
250 void TouchSelectionController::ActivateSelection() {
251 DCHECK(!is_insertion_active_);
252
253 if (!start_selection_handle_)
254 start_selection_handle_.reset(new TouchHandle(this, start_orientation_));
255 else
256 start_selection_handle_->SetOrientation(start_orientation_);
257
258 if (!end_selection_handle_)
259 end_selection_handle_.reset(new TouchHandle(this, end_orientation_));
260 else
261 end_selection_handle_->SetOrientation(end_orientation_);
262
263 if (!is_selection_active_) {
264 is_selection_active_ = true;
265 client_->OnSelectionEvent(SELECTION_SHOWN, GetStartPosition());
266 }
267 }
268
269 void TouchSelectionController::DeactivateSelection() {
270 if (!is_selection_active_)
271 return;
272 DCHECK(start_selection_handle_);
273 DCHECK(end_selection_handle_);
274 start_selection_handle_->Hide();
275 end_selection_handle_->Hide();
276 is_selection_active_ = false;
277 client_->OnSelectionEvent(SELECTION_CLEARED, gfx::PointF());
278 }
279
280 void TouchSelectionController::ResetCachedValues() {
281 start_rect_ = gfx::RectF();
282 end_rect_ = gfx::RectF();
283 start_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
284 end_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
285 start_visible_ = false;
286 end_visible_ = false;
287 selection_editable_for_last_update_ = false;
288 }
289
290 gfx::PointF TouchSelectionController::GetStartPosition() const {
291 return start_rect_.bottom_left();
292 }
293
294 gfx::PointF TouchSelectionController::GetEndPosition() const {
295 return end_rect_.bottom_left();
296 }
297
298 float TouchSelectionController::GetStartLineHeight() const {
299 return start_rect_.height();
300 }
301
302 float TouchSelectionController::GetEndLineHeight() const {
303 return end_rect_.height();
304 }
305
306 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698