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

Side by Side Diff: ui/touch_selection/touch_selection_controller.cc

Issue 1066053002: [Android] Allow custom ActionMode creation via ContentViewClient (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 8 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/touch_selection/touch_selection_controller.h" 5 #include "ui/touch_selection/touch_selection_controller.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 10
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 223
224 if (is_selection_active_) { 224 if (is_selection_active_) {
225 bool needs_animate = start_selection_handle_->Animate(frame_time); 225 bool needs_animate = start_selection_handle_->Animate(frame_time);
226 needs_animate |= end_selection_handle_->Animate(frame_time); 226 needs_animate |= end_selection_handle_->Animate(frame_time);
227 return needs_animate; 227 return needs_animate;
228 } 228 }
229 229
230 return false; 230 return false;
231 } 231 }
232 232
233 gfx::RectF TouchSelectionController::GetRectBetweenBounds() const {
234 // Short-circuit for efficiency.
235 if (!is_insertion_active_ && !is_selection_active_)
236 return gfx::RectF();
237
238 if (start_.visible() && !end_.visible())
239 return gfx::BoundingRect(start_.edge_top(), start_.edge_bottom());
240
241 if (end_.visible() && !start_.visible())
242 return gfx::BoundingRect(end_.edge_top(), end_.edge_bottom());
243
244 // If both handles are visible, or both are invisible, use the entire rect.
245 return RectFBetweenSelectionBounds(start_, end_);
mfomitchev 2015/04/14 15:02:33 Can't we also have a case when non are visible (bu
jdduke (slow) 2015/04/14 15:19:30 For sure, but I think the controller should be som
246 }
247
248 gfx::RectF TouchSelectionController::GetRectBetweenBoundsIncludingHandles()
mfomitchev 2015/04/14 15:02:33 Having a method returning MaxHandleImageSize/MaxHa
jdduke (slow) 2015/04/14 15:19:30 Well, we may simply have to differ between platfor
249 const {
250 gfx::RectF rect = GetRectBetweenBounds();
251 if (rect.IsEmpty())
252 return rect;
253
254 if (is_insertion_active_) {
255 rect.Union(insertion_handle_->GetVisibleBounds());
256 } else if (is_selection_active_) {
257 rect.Union(start_selection_handle_->GetVisibleBounds());
258 rect.Union(end_selection_handle_->GetVisibleBounds());
259 }
260
261 return rect;
262 }
263
264 const gfx::PointF& TouchSelectionController::GetStartPosition() const {
265 return start_.edge_bottom();
266 }
267
268 const gfx::PointF& TouchSelectionController::GetEndPosition() const {
269 return end_.edge_bottom();
270 }
271
233 void TouchSelectionController::OnHandleDragBegin(const TouchHandle& handle) { 272 void TouchSelectionController::OnHandleDragBegin(const TouchHandle& handle) {
234 if (&handle == insertion_handle_.get()) { 273 if (&handle == insertion_handle_.get()) {
235 client_->OnSelectionEvent(INSERTION_DRAG_STARTED, handle.position()); 274 client_->OnSelectionEvent(INSERTION_DRAG_STARTED);
236 return; 275 return;
237 } 276 }
238 277
239 gfx::PointF base, extent; 278 gfx::PointF base, extent;
240 if (&handle == start_selection_handle_.get()) { 279 if (&handle == start_selection_handle_.get()) {
241 base = end_selection_handle_->position() + GetEndLineOffset(); 280 base = end_selection_handle_->position() + GetEndLineOffset();
242 extent = start_selection_handle_->position() + GetStartLineOffset(); 281 extent = start_selection_handle_->position() + GetStartLineOffset();
243 } else { 282 } else {
244 base = start_selection_handle_->position() + GetStartLineOffset(); 283 base = start_selection_handle_->position() + GetStartLineOffset();
245 extent = end_selection_handle_->position() + GetEndLineOffset(); 284 extent = end_selection_handle_->position() + GetEndLineOffset();
246 } 285 }
247 selection_handle_dragged_ = true; 286 selection_handle_dragged_ = true;
248 287
249 // When moving the handle we want to move only the extent point. Before doing 288 // When moving the handle we want to move only the extent point. Before doing
250 // so we must make sure that the base point is set correctly. 289 // so we must make sure that the base point is set correctly.
251 client_->SelectBetweenCoordinates(base, extent); 290 client_->SelectBetweenCoordinates(base, extent);
252 291 client_->OnSelectionEvent(SELECTION_DRAG_STARTED);
253 client_->OnSelectionEvent(SELECTION_DRAG_STARTED, handle.position());
254 } 292 }
255 293
256 void TouchSelectionController::OnHandleDragUpdate(const TouchHandle& handle, 294 void TouchSelectionController::OnHandleDragUpdate(const TouchHandle& handle,
257 const gfx::PointF& position) { 295 const gfx::PointF& position) {
258 // As the position corresponds to the bottom left point of the selection 296 // As the position corresponds to the bottom left point of the selection
259 // bound, offset it by half the corresponding line height. 297 // bound, offset it by half the corresponding line height.
260 gfx::Vector2dF line_offset = &handle == start_selection_handle_.get() 298 gfx::Vector2dF line_offset = &handle == start_selection_handle_.get()
261 ? GetStartLineOffset() 299 ? GetStartLineOffset()
262 : GetEndLineOffset(); 300 : GetEndLineOffset();
263 gfx::PointF line_position = position + line_offset; 301 gfx::PointF line_position = position + line_offset;
264 if (&handle == insertion_handle_.get()) { 302 if (&handle == insertion_handle_.get()) {
265 client_->MoveCaret(line_position); 303 client_->MoveCaret(line_position);
266 } else { 304 } else {
267 client_->MoveRangeSelectionExtent(line_position); 305 client_->MoveRangeSelectionExtent(line_position);
268 } 306 }
269 } 307 }
270 308
271 void TouchSelectionController::OnHandleDragEnd(const TouchHandle& handle) { 309 void TouchSelectionController::OnHandleDragEnd(const TouchHandle& handle) {
272 if (&handle == insertion_handle_.get()) 310 if (&handle == insertion_handle_.get())
273 client_->OnSelectionEvent(INSERTION_DRAG_STOPPED, handle.position()); 311 client_->OnSelectionEvent(INSERTION_DRAG_STOPPED);
274 else 312 else
275 client_->OnSelectionEvent(SELECTION_DRAG_STOPPED, handle.position()); 313 client_->OnSelectionEvent(SELECTION_DRAG_STOPPED);
276 } 314 }
277 315
278 void TouchSelectionController::OnHandleTapped(const TouchHandle& handle) { 316 void TouchSelectionController::OnHandleTapped(const TouchHandle& handle) {
279 if (insertion_handle_ && &handle == insertion_handle_.get()) 317 if (insertion_handle_ && &handle == insertion_handle_.get())
280 client_->OnSelectionEvent(INSERTION_TAPPED, handle.position()); 318 client_->OnSelectionEvent(INSERTION_TAPPED);
281 } 319 }
282 320
283 void TouchSelectionController::SetNeedsAnimate() { 321 void TouchSelectionController::SetNeedsAnimate() {
284 client_->SetNeedsAnimate(); 322 client_->SetNeedsAnimate();
285 } 323 }
286 324
287 scoped_ptr<TouchHandleDrawable> TouchSelectionController::CreateDrawable() { 325 scoped_ptr<TouchHandleDrawable> TouchSelectionController::CreateDrawable() {
288 return client_->CreateDrawable(); 326 return client_->CreateDrawable();
289 } 327 }
290 328
(...skipping 29 matching lines...) Expand all
320 } 358 }
321 359
322 if (!activate_insertion_automatically_) 360 if (!activate_insertion_automatically_)
323 return; 361 return;
324 362
325 const bool was_active = is_insertion_active_; 363 const bool was_active = is_insertion_active_;
326 const gfx::PointF position = GetStartPosition(); 364 const gfx::PointF position = GetStartPosition();
327 if (!is_insertion_active_) 365 if (!is_insertion_active_)
328 ActivateInsertion(); 366 ActivateInsertion();
329 else 367 else
330 client_->OnSelectionEvent(INSERTION_MOVED, position); 368 client_->OnSelectionEvent(INSERTION_MOVED);
331 369
332 insertion_handle_->SetVisible(GetStartVisible(), 370 insertion_handle_->SetVisible(GetStartVisible(),
333 GetAnimationStyle(was_active)); 371 GetAnimationStyle(was_active));
334 insertion_handle_->SetPosition(position); 372 insertion_handle_->SetPosition(position);
335 } 373 }
336 374
337 void TouchSelectionController::OnSelectionChanged() { 375 void TouchSelectionController::OnSelectionChanged() {
338 DeactivateInsertion(); 376 DeactivateInsertion();
339 377
340 if (!activate_selection_automatically_) 378 if (!activate_selection_automatically_)
341 return; 379 return;
342 380
343 const bool was_active = is_selection_active_; 381 const bool was_active = is_selection_active_;
344 ActivateSelection(); 382 if (!is_selection_active_ || response_pending_input_event_ == LONG_PRESS)
383 ActivateSelection();
384 else
385 client_->OnSelectionEvent(SELECTION_MOVED);
345 386
346 const TouchHandle::AnimationStyle animation = GetAnimationStyle(was_active); 387 const TouchHandle::AnimationStyle animation = GetAnimationStyle(was_active);
347 start_selection_handle_->SetVisible(GetStartVisible(), animation); 388 start_selection_handle_->SetVisible(GetStartVisible(), animation);
348 end_selection_handle_->SetVisible(GetEndVisible(), animation); 389 end_selection_handle_->SetVisible(GetEndVisible(), animation);
349 390
350 start_selection_handle_->SetPosition(GetStartPosition()); 391 start_selection_handle_->SetPosition(GetStartPosition());
351 end_selection_handle_->SetPosition(GetEndPosition()); 392 end_selection_handle_->SetPosition(GetEndPosition());
352 } 393 }
353 394
354 void TouchSelectionController::ActivateInsertion() { 395 void TouchSelectionController::ActivateInsertion() {
355 DCHECK(!is_selection_active_); 396 DCHECK(!is_selection_active_);
356 397
357 if (!insertion_handle_) 398 if (!insertion_handle_)
358 insertion_handle_.reset( 399 insertion_handle_.reset(
359 new TouchHandle(this, TouchHandleOrientation::CENTER)); 400 new TouchHandle(this, TouchHandleOrientation::CENTER));
360 401
361 if (!is_insertion_active_) { 402 if (!is_insertion_active_) {
362 is_insertion_active_ = true; 403 is_insertion_active_ = true;
363 insertion_handle_->SetEnabled(true); 404 insertion_handle_->SetEnabled(true);
364 client_->OnSelectionEvent(INSERTION_SHOWN, GetStartPosition()); 405 client_->OnSelectionEvent(INSERTION_SHOWN);
365 } 406 }
366 } 407 }
367 408
368 void TouchSelectionController::DeactivateInsertion() { 409 void TouchSelectionController::DeactivateInsertion() {
369 if (!is_insertion_active_) 410 if (!is_insertion_active_)
370 return; 411 return;
371 DCHECK(insertion_handle_); 412 DCHECK(insertion_handle_);
372 is_insertion_active_ = false; 413 is_insertion_active_ = false;
373 insertion_handle_->SetEnabled(false); 414 insertion_handle_->SetEnabled(false);
374 client_->OnSelectionEvent(INSERTION_CLEARED, gfx::PointF()); 415 client_->OnSelectionEvent(INSERTION_CLEARED);
375 } 416 }
376 417
377 void TouchSelectionController::ActivateSelection() { 418 void TouchSelectionController::ActivateSelection() {
378 DCHECK(!is_insertion_active_); 419 DCHECK(!is_insertion_active_);
379 420
380 if (!start_selection_handle_) { 421 if (!start_selection_handle_) {
381 start_selection_handle_.reset(new TouchHandle(this, start_orientation_)); 422 start_selection_handle_.reset(new TouchHandle(this, start_orientation_));
382 } else { 423 } else {
383 start_selection_handle_->SetEnabled(true); 424 start_selection_handle_->SetEnabled(true);
384 start_selection_handle_->SetOrientation(start_orientation_); 425 start_selection_handle_->SetOrientation(start_orientation_);
(...skipping 11 matching lines...) Expand all
396 // intervening SELECTION_CLEARED update to avoid unnecessary state changes. 437 // intervening SELECTION_CLEARED update to avoid unnecessary state changes.
397 if (!is_selection_active_ || response_pending_input_event_ == LONG_PRESS) { 438 if (!is_selection_active_ || response_pending_input_event_ == LONG_PRESS) {
398 if (is_selection_active_) { 439 if (is_selection_active_) {
399 // The active selection session finishes with the start of the new one. 440 // The active selection session finishes with the start of the new one.
400 LogSelectionEnd(); 441 LogSelectionEnd();
401 } 442 }
402 is_selection_active_ = true; 443 is_selection_active_ = true;
403 selection_handle_dragged_ = false; 444 selection_handle_dragged_ = false;
404 selection_start_time_ = base::TimeTicks::Now(); 445 selection_start_time_ = base::TimeTicks::Now();
405 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE; 446 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
406 client_->OnSelectionEvent(SELECTION_SHOWN, GetStartPosition()); 447 client_->OnSelectionEvent(SELECTION_SHOWN);
407 } 448 }
408 } 449 }
409 450
410 void TouchSelectionController::DeactivateSelection() { 451 void TouchSelectionController::DeactivateSelection() {
411 if (!is_selection_active_) 452 if (!is_selection_active_)
412 return; 453 return;
413 DCHECK(start_selection_handle_); 454 DCHECK(start_selection_handle_);
414 DCHECK(end_selection_handle_); 455 DCHECK(end_selection_handle_);
415 LogSelectionEnd(); 456 LogSelectionEnd();
416 start_selection_handle_->SetEnabled(false); 457 start_selection_handle_->SetEnabled(false);
417 end_selection_handle_->SetEnabled(false); 458 end_selection_handle_->SetEnabled(false);
418 is_selection_active_ = false; 459 is_selection_active_ = false;
419 client_->OnSelectionEvent(SELECTION_CLEARED, gfx::PointF()); 460 client_->OnSelectionEvent(SELECTION_CLEARED);
420 } 461 }
421 462
422 void TouchSelectionController::ResetCachedValuesIfInactive() { 463 void TouchSelectionController::ResetCachedValuesIfInactive() {
423 if (is_selection_active_ || is_insertion_active_) 464 if (is_selection_active_ || is_insertion_active_)
424 return; 465 return;
425 start_ = SelectionBound(); 466 start_ = SelectionBound();
426 end_ = SelectionBound(); 467 end_ = SelectionBound();
427 start_orientation_ = TouchHandleOrientation::UNDEFINED; 468 start_orientation_ = TouchHandleOrientation::UNDEFINED;
428 end_orientation_ = TouchHandleOrientation::UNDEFINED; 469 end_orientation_ = TouchHandleOrientation::UNDEFINED;
429 } 470 }
430 471
431 const gfx::PointF& TouchSelectionController::GetStartPosition() const {
432 return start_.edge_bottom();
433 }
434
435 const gfx::PointF& TouchSelectionController::GetEndPosition() const {
436 return end_.edge_bottom();
437 }
438
439 gfx::Vector2dF TouchSelectionController::GetStartLineOffset() const { 472 gfx::Vector2dF TouchSelectionController::GetStartLineOffset() const {
440 return ComputeLineOffsetFromBottom(start_); 473 return ComputeLineOffsetFromBottom(start_);
441 } 474 }
442 475
443 gfx::Vector2dF TouchSelectionController::GetEndLineOffset() const { 476 gfx::Vector2dF TouchSelectionController::GetEndLineOffset() const {
444 return ComputeLineOffsetFromBottom(end_); 477 return ComputeLineOffsetFromBottom(end_);
445 } 478 }
446 479
447 bool TouchSelectionController::GetStartVisible() const { 480 bool TouchSelectionController::GetStartVisible() const {
448 return start_.visible() && !temporarily_hidden_; 481 return start_.visible() && !temporarily_hidden_;
(...skipping 19 matching lines...) Expand all
468 base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_; 501 base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_;
469 UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.WasDraggedDuration", 502 UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.WasDraggedDuration",
470 duration, 503 duration,
471 base::TimeDelta::FromMilliseconds(500), 504 base::TimeDelta::FromMilliseconds(500),
472 base::TimeDelta::FromSeconds(60), 505 base::TimeDelta::FromSeconds(60),
473 60); 506 60);
474 } 507 }
475 } 508 }
476 509
477 } // namespace ui 510 } // namespace ui
OLDNEW
« no previous file with comments | « ui/touch_selection/touch_selection_controller.h ('k') | ui/touch_selection/touch_selection_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698