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

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

Issue 481683003: Support for Adaptive Handle Orientation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review comments Created 5 years, 2 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 25 matching lines...) Expand all
36 } 36 }
37 NOTREACHED() << "Invalid selection bound type: " << type; 37 NOTREACHED() << "Invalid selection bound type: " << type;
38 return TouchHandleOrientation::UNDEFINED; 38 return TouchHandleOrientation::UNDEFINED;
39 } 39 }
40 40
41 } // namespace 41 } // namespace
42 42
43 TouchSelectionController::Config::Config() 43 TouchSelectionController::Config::Config()
44 : max_tap_duration(base::TimeDelta::FromMilliseconds(300)), 44 : max_tap_duration(base::TimeDelta::FromMilliseconds(300)),
45 tap_slop(8), 45 tap_slop(8),
46 enable_adaptive_handle_orientation(false),
46 enable_longpress_drag_selection(false), 47 enable_longpress_drag_selection(false),
47 show_on_tap_for_empty_editable(false) {} 48 show_on_tap_for_empty_editable(false) {}
48 49
49 TouchSelectionController::Config::~Config() { 50 TouchSelectionController::Config::~Config() {
50 } 51 }
51 52
52 TouchSelectionController::TouchSelectionController( 53 TouchSelectionController::TouchSelectionController(
53 TouchSelectionControllerClient* client, 54 TouchSelectionControllerClient* client,
54 const Config& config) 55 const Config& config)
55 : client_(client), 56 : client_(client),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 137
137 if (start_orientation_ == TouchHandleOrientation::CENTER && 138 if (start_orientation_ == TouchHandleOrientation::CENTER &&
138 selection_editable_) { 139 selection_editable_) {
139 OnInsertionChanged(); 140 OnInsertionChanged();
140 return; 141 return;
141 } 142 }
142 143
143 HideAndDisallowShowingAutomatically(); 144 HideAndDisallowShowingAutomatically();
144 } 145 }
145 146
147 void TouchSelectionController::OnViewportChanged(
148 const gfx::RectF viewport_rect) {
149 // Trigger a force update if the viewport is changed, so that
150 // it triggers a call to change the mirror values if required.
151 if (viewport_rect_ == viewport_rect)
152 return;
153
154 viewport_rect_ = viewport_rect;
155
156 if (active_status_ == INACTIVE)
157 return;
158
159 if (active_status_ == INSERTION_ACTIVE) {
160 DCHECK(insertion_handle_);
161 insertion_handle_->SetViewportRect(viewport_rect);
162 } else if (active_status_ == SELECTION_ACTIVE) {
163 DCHECK(start_selection_handle_);
164 DCHECK(end_selection_handle_);
165 start_selection_handle_->SetViewportRect(viewport_rect);
166 end_selection_handle_->SetViewportRect(viewport_rect);
167 }
168
169 // Update handle layout after setting the new Viewport size.
170 UpdateHandleLayoutIfNecessary();
171 }
172
146 bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) { 173 bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) {
147 if (config_.enable_longpress_drag_selection && 174 if (config_.enable_longpress_drag_selection &&
148 longpress_drag_selector_.WillHandleTouchEvent(event)) { 175 longpress_drag_selector_.WillHandleTouchEvent(event)) {
149 return true; 176 return true;
150 } 177 }
151 178
152 if (active_status_ == INSERTION_ACTIVE) { 179 if (active_status_ == INSERTION_ACTIVE) {
153 DCHECK(insertion_handle_); 180 DCHECK(insertion_handle_);
154 return insertion_handle_->WillHandleTouchEvent(event); 181 return insertion_handle_->WillHandleTouchEvent(event);
155 } 182 }
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 } 401 }
375 402
376 scoped_ptr<TouchHandleDrawable> TouchSelectionController::CreateDrawable() { 403 scoped_ptr<TouchHandleDrawable> TouchSelectionController::CreateDrawable() {
377 return client_->CreateDrawable(); 404 return client_->CreateDrawable();
378 } 405 }
379 406
380 base::TimeDelta TouchSelectionController::GetMaxTapDuration() const { 407 base::TimeDelta TouchSelectionController::GetMaxTapDuration() const {
381 return config_.max_tap_duration; 408 return config_.max_tap_duration;
382 } 409 }
383 410
411 bool TouchSelectionController::IsAdaptiveHandleOrientationEnabled() const {
412 return config_.enable_adaptive_handle_orientation;
413 }
414
384 void TouchSelectionController::OnLongPressDragActiveStateChanged() { 415 void TouchSelectionController::OnLongPressDragActiveStateChanged() {
385 // The handles should remain hidden for the duration of a longpress drag, 416 // The handles should remain hidden for the duration of a longpress drag,
386 // including the time between a longpress and the start of drag motion. 417 // including the time between a longpress and the start of drag motion.
387 RefreshHandleVisibility(); 418 RefreshHandleVisibility();
388 } 419 }
389 420
390 gfx::PointF TouchSelectionController::GetSelectionStart() const { 421 gfx::PointF TouchSelectionController::GetSelectionStart() const {
391 return GetStartPosition(); 422 return GetStartPosition();
392 } 423 }
393 424
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 HideAndDisallowShowingAutomatically(); 464 HideAndDisallowShowingAutomatically();
434 return; 465 return;
435 } 466 }
436 467
437 if (!activate_insertion_automatically_) 468 if (!activate_insertion_automatically_)
438 return; 469 return;
439 470
440 const bool activated = ActivateInsertionIfNecessary(); 471 const bool activated = ActivateInsertionIfNecessary();
441 472
442 const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated); 473 const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated);
474 insertion_handle_->SetFocus(start_.edge_top(), start_.edge_bottom());
443 insertion_handle_->SetVisible(GetStartVisible(), animation); 475 insertion_handle_->SetVisible(GetStartVisible(), animation);
444 insertion_handle_->SetPosition(GetStartPosition()); 476
477 UpdateHandleLayoutIfNecessary();
445 478
446 client_->OnSelectionEvent(activated ? INSERTION_HANDLE_SHOWN 479 client_->OnSelectionEvent(activated ? INSERTION_HANDLE_SHOWN
447 : INSERTION_HANDLE_MOVED); 480 : INSERTION_HANDLE_MOVED);
448 } 481 }
449 482
450 void TouchSelectionController::OnSelectionChanged() { 483 void TouchSelectionController::OnSelectionChanged() {
451 DeactivateInsertion(); 484 DeactivateInsertion();
452 485
453 if (!activate_selection_automatically_) 486 if (!activate_selection_automatically_)
454 return; 487 return;
455 488
456 const bool activated = ActivateSelectionIfNecessary(); 489 const bool activated = ActivateSelectionIfNecessary();
457 490
458 const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated); 491 const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated);
492
493 start_selection_handle_->SetFocus(start_.edge_top(), start_.edge_bottom());
494 end_selection_handle_->SetFocus(end_.edge_top(), end_.edge_bottom());
495
496 start_selection_handle_->SetOrientation(start_orientation_);
497 end_selection_handle_->SetOrientation(end_orientation_);
498
459 start_selection_handle_->SetVisible(GetStartVisible(), animation); 499 start_selection_handle_->SetVisible(GetStartVisible(), animation);
460 end_selection_handle_->SetVisible(GetEndVisible(), animation); 500 end_selection_handle_->SetVisible(GetEndVisible(), animation);
461 start_selection_handle_->SetPosition(GetStartPosition()); 501
462 end_selection_handle_->SetPosition(GetEndPosition()); 502 UpdateHandleLayoutIfNecessary();
463 503
464 client_->OnSelectionEvent(activated ? SELECTION_HANDLES_SHOWN 504 client_->OnSelectionEvent(activated ? SELECTION_HANDLES_SHOWN
465 : SELECTION_HANDLES_MOVED); 505 : SELECTION_HANDLES_MOVED);
466 } 506 }
467 507
468 bool TouchSelectionController::ActivateInsertionIfNecessary() { 508 bool TouchSelectionController::ActivateInsertionIfNecessary() {
469 DCHECK_NE(SELECTION_ACTIVE, active_status_); 509 DCHECK_NE(SELECTION_ACTIVE, active_status_);
470 510
471 if (!insertion_handle_) { 511 if (!insertion_handle_) {
472 insertion_handle_.reset( 512 insertion_handle_.reset(
473 new TouchHandle(this, TouchHandleOrientation::CENTER)); 513 new TouchHandle(this, TouchHandleOrientation::CENTER, viewport_rect_));
474 } 514 }
475 515
476 if (active_status_ == INACTIVE) { 516 if (active_status_ == INACTIVE) {
477 active_status_ = INSERTION_ACTIVE; 517 active_status_ = INSERTION_ACTIVE;
478 insertion_handle_->SetEnabled(true); 518 insertion_handle_->SetEnabled(true);
519 insertion_handle_->SetViewportRect(viewport_rect_);
479 return true; 520 return true;
480 } 521 }
481 return false; 522 return false;
482 } 523 }
483 524
484 void TouchSelectionController::DeactivateInsertion() { 525 void TouchSelectionController::DeactivateInsertion() {
485 if (active_status_ != INSERTION_ACTIVE) 526 if (active_status_ != INSERTION_ACTIVE)
486 return; 527 return;
487 DCHECK(insertion_handle_); 528 DCHECK(insertion_handle_);
488 active_status_ = INACTIVE; 529 active_status_ = INACTIVE;
489 insertion_handle_->SetEnabled(false); 530 insertion_handle_->SetEnabled(false);
490 client_->OnSelectionEvent(INSERTION_HANDLE_CLEARED); 531 client_->OnSelectionEvent(INSERTION_HANDLE_CLEARED);
491 } 532 }
492 533
493 bool TouchSelectionController::ActivateSelectionIfNecessary() { 534 bool TouchSelectionController::ActivateSelectionIfNecessary() {
494 DCHECK_NE(INSERTION_ACTIVE, active_status_); 535 DCHECK_NE(INSERTION_ACTIVE, active_status_);
495 536
496 if (!start_selection_handle_) { 537 if (!start_selection_handle_) {
497 start_selection_handle_.reset(new TouchHandle(this, start_orientation_)); 538 start_selection_handle_.reset(
539 new TouchHandle(this, start_orientation_, viewport_rect_));
498 } else { 540 } else {
499 start_selection_handle_->SetEnabled(true); 541 start_selection_handle_->SetEnabled(true);
500 start_selection_handle_->SetOrientation(start_orientation_); 542 start_selection_handle_->SetViewportRect(viewport_rect_);
501 } 543 }
502 544
503 if (!end_selection_handle_) { 545 if (!end_selection_handle_) {
504 end_selection_handle_.reset(new TouchHandle(this, end_orientation_)); 546 end_selection_handle_.reset(
547 new TouchHandle(this, end_orientation_, viewport_rect_));
505 } else { 548 } else {
506 end_selection_handle_->SetEnabled(true); 549 end_selection_handle_->SetEnabled(true);
507 end_selection_handle_->SetOrientation(end_orientation_); 550 end_selection_handle_->SetViewportRect(viewport_rect_);
508 } 551 }
509 552
510 // As a long press received while a selection is already active may trigger 553 // As a long press received while a selection is already active may trigger
511 // an entirely new selection, notify the client but avoid sending an 554 // an entirely new selection, notify the client but avoid sending an
512 // intervening SELECTION_HANDLES_CLEARED update to avoid unnecessary state 555 // intervening SELECTION_HANDLES_CLEARED update to avoid unnecessary state
513 // changes. 556 // changes.
514 if (active_status_ == INACTIVE || 557 if (active_status_ == INACTIVE ||
515 response_pending_input_event_ == LONG_PRESS) { 558 response_pending_input_event_ == LONG_PRESS) {
516 if (active_status_ == SELECTION_ACTIVE) { 559 if (active_status_ == SELECTION_ACTIVE) {
517 // The active selection session finishes with the start of the new one. 560 // The active selection session finishes with the start of the new one.
(...skipping 26 matching lines...) Expand all
544 // Only force the update if the reported selection is non-empty but still 587 // Only force the update if the reported selection is non-empty but still
545 // considered "inactive", i.e., it wasn't preceded by a user gesture or 588 // considered "inactive", i.e., it wasn't preceded by a user gesture or
546 // the handles have since been explicitly hidden. 589 // the handles have since been explicitly hidden.
547 if (active_status_ == INACTIVE && 590 if (active_status_ == INACTIVE &&
548 start_.type() != SelectionBound::EMPTY && 591 start_.type() != SelectionBound::EMPTY &&
549 end_.type() != SelectionBound::EMPTY) { 592 end_.type() != SelectionBound::EMPTY) {
550 force_next_update_ = true; 593 force_next_update_ = true;
551 } 594 }
552 } 595 }
553 596
597 void TouchSelectionController::UpdateHandleLayoutIfNecessary() {
598 if (active_status_ == INSERTION_ACTIVE) {
599 DCHECK(insertion_handle_);
600 insertion_handle_->UpdateHandleLayout();
601 } else if (active_status_ == SELECTION_ACTIVE) {
602 DCHECK(start_selection_handle_);
603 DCHECK(end_selection_handle_);
604 start_selection_handle_->UpdateHandleLayout();
605 end_selection_handle_->UpdateHandleLayout();
606 }
607 }
608
554 void TouchSelectionController::RefreshHandleVisibility() { 609 void TouchSelectionController::RefreshHandleVisibility() {
555 TouchHandle::AnimationStyle animation_style = GetAnimationStyle(true); 610 TouchHandle::AnimationStyle animation_style = GetAnimationStyle(true);
556 if (active_status_ == SELECTION_ACTIVE) { 611 if (active_status_ == SELECTION_ACTIVE) {
557 start_selection_handle_->SetVisible(GetStartVisible(), animation_style); 612 start_selection_handle_->SetVisible(GetStartVisible(), animation_style);
558 end_selection_handle_->SetVisible(GetEndVisible(), animation_style); 613 end_selection_handle_->SetVisible(GetEndVisible(), animation_style);
559 } 614 }
560 if (active_status_ == INSERTION_ACTIVE) 615 if (active_status_ == INSERTION_ACTIVE)
561 insertion_handle_->SetVisible(GetStartVisible(), animation_style); 616 insertion_handle_->SetVisible(GetStartVisible(), animation_style);
617
618 // Update handle layout if handle visibility is explicitly changed.
619 UpdateHandleLayoutIfNecessary();
562 } 620 }
563 621
564 gfx::Vector2dF TouchSelectionController::GetStartLineOffset() const { 622 gfx::Vector2dF TouchSelectionController::GetStartLineOffset() const {
565 return ComputeLineOffsetFromBottom(start_); 623 return ComputeLineOffsetFromBottom(start_);
566 } 624 }
567 625
568 gfx::Vector2dF TouchSelectionController::GetEndLineOffset() const { 626 gfx::Vector2dF TouchSelectionController::GetEndLineOffset() const {
569 return ComputeLineOffsetFromBottom(end_); 627 return ComputeLineOffsetFromBottom(end_);
570 } 628 }
571 629
(...skipping 27 matching lines...) Expand all
599 base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_; 657 base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_;
600 UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.WasDraggedDuration", 658 UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.WasDraggedDuration",
601 duration, 659 duration,
602 base::TimeDelta::FromMilliseconds(500), 660 base::TimeDelta::FromMilliseconds(500),
603 base::TimeDelta::FromSeconds(60), 661 base::TimeDelta::FromSeconds(60),
604 60); 662 60);
605 } 663 }
606 } 664 }
607 665
608 } // namespace ui 666 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698