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

Side by Side Diff: ui/views/controls/textfield/textfield.cc

Issue 407993003: Fix gesture handling for Views textfields (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/views/controls/textfield/textfield.h" 5 #include "ui/views/controls/textfield/textfield.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "grit/ui_strings.h" 10 #include "grit/ui_strings.h"
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 selection_text_color_(SK_ColorWHITE), 264 selection_text_color_(SK_ColorWHITE),
265 selection_background_color_(SK_ColorBLUE), 265 selection_background_color_(SK_ColorBLUE),
266 placeholder_text_color_(kDefaultPlaceholderTextColor), 266 placeholder_text_color_(kDefaultPlaceholderTextColor),
267 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), 267 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT),
268 performing_user_action_(false), 268 performing_user_action_(false),
269 skip_input_method_cancel_composition_(false), 269 skip_input_method_cancel_composition_(false),
270 cursor_visible_(false), 270 cursor_visible_(false),
271 drop_cursor_visible_(false), 271 drop_cursor_visible_(false),
272 initiating_drag_(false), 272 initiating_drag_(false),
273 aggregated_clicks_(0), 273 aggregated_clicks_(0),
274 drag_start_display_offset_(0),
275 touch_handles_hidden_due_to_scroll_(false),
274 weak_ptr_factory_(this) { 276 weak_ptr_factory_(this) {
275 set_context_menu_controller(this); 277 set_context_menu_controller(this);
276 set_drag_controller(this); 278 set_drag_controller(this);
277 SetBorder(scoped_ptr<Border>(new FocusableBorder())); 279 SetBorder(scoped_ptr<Border>(new FocusableBorder()));
278 SetFocusable(true); 280 SetFocusable(true);
279 281
280 if (ViewsDelegate::views_delegate) { 282 if (ViewsDelegate::views_delegate) {
281 password_reveal_duration_ = ViewsDelegate::views_delegate-> 283 password_reveal_duration_ = ViewsDelegate::views_delegate->
282 GetDefaultTextfieldObscuredRevealDuration(); 284 GetDefaultTextfieldObscuredRevealDuration();
283 } 285 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 base::string16 Textfield::GetSelectedText() const { 335 base::string16 Textfield::GetSelectedText() const {
334 return model_->GetSelectedText(); 336 return model_->GetSelectedText();
335 } 337 }
336 338
337 void Textfield::SelectAll(bool reversed) { 339 void Textfield::SelectAll(bool reversed) {
338 model_->SelectAll(reversed); 340 model_->SelectAll(reversed);
339 UpdateSelectionClipboard(); 341 UpdateSelectionClipboard();
340 UpdateAfterChange(false, true); 342 UpdateAfterChange(false, true);
341 } 343 }
342 344
345 void Textfield::SelectWordAt(const gfx::Point& point) {
346 model_->MoveCursorTo(point, false);
347 model_->SelectWord();
348 UpdateAfterChange(false, true);
349 }
350
343 void Textfield::ClearSelection() { 351 void Textfield::ClearSelection() {
344 model_->ClearSelection(); 352 model_->ClearSelection();
345 UpdateAfterChange(false, true); 353 UpdateAfterChange(false, true);
346 } 354 }
347 355
348 bool Textfield::HasSelection() const { 356 bool Textfield::HasSelection() const {
349 return !GetSelectedRange().is_empty(); 357 return !GetSelectedRange().is_empty();
350 } 358 }
351 359
352 SkColor Textfield::GetTextColor() const { 360 SkColor Textfield::GetTextColor() const {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 OnBeforeUserAction(); 584 OnBeforeUserAction();
577 initiating_drag_ = false; 585 initiating_drag_ = false;
578 switch (aggregated_clicks_) { 586 switch (aggregated_clicks_) {
579 case 0: 587 case 0:
580 if (GetRenderText()->IsPointInSelection(event.location())) 588 if (GetRenderText()->IsPointInSelection(event.location()))
581 initiating_drag_ = true; 589 initiating_drag_ = true;
582 else 590 else
583 MoveCursorTo(event.location(), event.IsShiftDown()); 591 MoveCursorTo(event.location(), event.IsShiftDown());
584 break; 592 break;
585 case 1: 593 case 1:
586 model_->MoveCursorTo(event.location(), false); 594 SelectWordAt(event.location());
587 model_->SelectWord();
588 UpdateAfterChange(false, true);
589 double_click_word_ = GetRenderText()->selection(); 595 double_click_word_ = GetRenderText()->selection();
590 break; 596 break;
591 case 2: 597 case 2:
592 SelectAll(false); 598 SelectAll(false);
593 break; 599 break;
594 default: 600 default:
595 NOTREACHED(); 601 NOTREACHED();
596 } 602 }
597 OnAfterUserAction(); 603 OnAfterUserAction();
598 } 604 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 return handled; 692 return handled;
687 } 693 }
688 694
689 ui::TextInputClient* Textfield::GetTextInputClient() { 695 ui::TextInputClient* Textfield::GetTextInputClient() {
690 return read_only_ ? NULL : this; 696 return read_only_ ? NULL : this;
691 } 697 }
692 698
693 void Textfield::OnGestureEvent(ui::GestureEvent* event) { 699 void Textfield::OnGestureEvent(ui::GestureEvent* event) {
694 switch (event->type()) { 700 switch (event->type()) {
695 case ui::ET_GESTURE_TAP_DOWN: 701 case ui::ET_GESTURE_TAP_DOWN:
696 OnBeforeUserAction();
697 RequestFocus(); 702 RequestFocus();
698 ShowImeIfNeeded(); 703 ShowImeIfNeeded();
699
700 // We don't deselect if the point is in the selection
701 // because TAP_DOWN may turn into a LONG_PRESS.
702 if (!GetRenderText()->IsPointInSelection(event->location()))
703 MoveCursorTo(event->location(), false);
704 OnAfterUserAction();
705 event->SetHandled();
706 break;
707 case ui::ET_GESTURE_SCROLL_UPDATE:
708 OnBeforeUserAction();
709 MoveCursorTo(event->location(), true);
710 OnAfterUserAction();
711 event->SetHandled();
712 break;
713 case ui::ET_GESTURE_SCROLL_END:
714 case ui::ET_SCROLL_FLING_START:
715 CreateTouchSelectionControllerAndNotifyIt();
716 event->SetHandled(); 704 event->SetHandled();
717 break; 705 break;
718 case ui::ET_GESTURE_TAP: 706 case ui::ET_GESTURE_TAP:
719 if (event->details().tap_count() == 1) { 707 if (event->details().tap_count() == 1) {
720 CreateTouchSelectionControllerAndNotifyIt(); 708 if (!GetRenderText()->IsPointInSelection(event->location())) {
709 OnBeforeUserAction();
710 MoveCursorTo(event->location(), false);
711 OnAfterUserAction();
712 }
713 } else if (event->details().tap_count() == 2) {
714 OnBeforeUserAction();
715 SelectWordAt(event->location());
716 OnAfterUserAction();
721 } else { 717 } else {
722 DestroyTouchSelection();
723 OnBeforeUserAction(); 718 OnBeforeUserAction();
724 SelectAll(false); 719 SelectAll(false);
725 OnAfterUserAction(); 720 OnAfterUserAction();
726 event->SetHandled();
727 } 721 }
722 CreateTouchSelectionControllerAndNotifyIt();
728 #if defined(OS_WIN) 723 #if defined(OS_WIN)
729 if (!read_only()) 724 if (!read_only())
730 base::win::DisplayVirtualKeyboard(); 725 base::win::DisplayVirtualKeyboard();
731 #endif 726 #endif
727 event->SetHandled();
732 break; 728 break;
733 case ui::ET_GESTURE_LONG_PRESS: 729 case ui::ET_GESTURE_LONG_PRESS:
734 // If long press happens outside selection, select word and show context
735 // menu (If touch selection is enabled, context menu is shown by the
736 // |touch_selection_controller_|, hence we mark the event handled.
737 // Otherwise, the regular context menu will be shown by views).
738 // If long press happens in selected text and touch drag drop is enabled,
739 // we will turn off touch selection (if one exists) and let views do drag
740 // drop.
741 if (!GetRenderText()->IsPointInSelection(event->location())) { 730 if (!GetRenderText()->IsPointInSelection(event->location())) {
731 // If long-press happens outside selection, select word and try to
732 // activate touch selection.
742 OnBeforeUserAction(); 733 OnBeforeUserAction();
743 model_->SelectWord(); 734 SelectWordAt(event->location());
744 touch_selection_controller_.reset(
745 ui::TouchSelectionController::create(this));
746 UpdateAfterChange(false, true);
747 OnAfterUserAction(); 735 OnAfterUserAction();
736 CreateTouchSelectionControllerAndNotifyIt();
737 // If touch selection activated successfully, mark event as handled so
738 // that the regular context menu is not shown.
748 if (touch_selection_controller_) 739 if (touch_selection_controller_)
749 event->SetHandled(); 740 event->SetHandled();
750 } else if (switches::IsTouchDragDropEnabled()) { 741 } else {
751 initiating_drag_ = true; 742 // If long-press happens on the selection, deactivate touch selection
743 // and try to initiate drag-drop. If drag-drop is not enabled, context
744 // menu will be shown. Event is not marked as handled to let Views
745 // handle drag-drop or context menu.
752 DestroyTouchSelection(); 746 DestroyTouchSelection();
753 } else { 747 initiating_drag_ = switches::IsTouchDragDropEnabled();
754 if (!touch_selection_controller_)
755 CreateTouchSelectionControllerAndNotifyIt();
756 if (touch_selection_controller_)
757 event->SetHandled();
758 } 748 }
759 return; 749 break;
760 case ui::ET_GESTURE_LONG_TAP: 750 case ui::ET_GESTURE_LONG_TAP:
761 if (!touch_selection_controller_)
762 CreateTouchSelectionControllerAndNotifyIt();
763
764 // If touch selection is enabled, the context menu on long tap will be 751 // If touch selection is enabled, the context menu on long tap will be
765 // shown by the |touch_selection_controller_|, hence we mark the event 752 // shown by the |touch_selection_controller_|, hence we mark the event
766 // handled so views does not try to show context menu on it. 753 // handled so Views does not try to show context menu on it.
767 if (touch_selection_controller_) 754 if (touch_selection_controller_)
768 event->SetHandled(); 755 event->SetHandled();
769 break; 756 break;
757 case ui::ET_GESTURE_SCROLL_BEGIN:
758 touch_handles_hidden_due_to_scroll_ = touch_selection_controller_;
sky 2014/07/21 22:37:43 I'm surprised you don't get a compile warning here
mohsen 2014/07/21 23:07:56 Really? Didn't know it's not allowed. Fixed.
759 DestroyTouchSelection();
760 drag_start_location_ = event->location();
761 drag_start_display_offset_ =
762 GetRenderText()->GetUpdatedDisplayOffset().x();
763 event->SetHandled();
764 break;
765 case ui::ET_GESTURE_SCROLL_UPDATE: {
766 int new_offset = drag_start_display_offset_ + event->location().x() -
767 drag_start_location_.x();
768 GetRenderText()->SetDisplayOffset(new_offset);
769 SchedulePaint();
770 event->SetHandled();
771 break;
772 }
773 case ui::ET_GESTURE_SCROLL_END:
774 case ui::ET_SCROLL_FLING_START:
775 if (touch_handles_hidden_due_to_scroll_) {
776 CreateTouchSelectionControllerAndNotifyIt();
777 touch_handles_hidden_due_to_scroll_ = false;
778 }
779 event->SetHandled();
780 break;
770 default: 781 default:
771 return; 782 return;
772 } 783 }
773 } 784 }
774 785
775 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { 786 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) {
776 SelectAll(false); 787 SelectAll(false);
777 } 788 }
778 789
779 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { 790 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after
1778 const size_t length = selection_clipboard_text.length(); 1789 const size_t length = selection_clipboard_text.length();
1779 range = gfx::Range(range.start() + length, range.end() + length); 1790 range = gfx::Range(range.start() + length, range.end() + length);
1780 } 1791 }
1781 model_->MoveCursorTo(gfx::SelectionModel(range, affinity)); 1792 model_->MoveCursorTo(gfx::SelectionModel(range, affinity));
1782 UpdateAfterChange(true, true); 1793 UpdateAfterChange(true, true);
1783 OnAfterUserAction(); 1794 OnAfterUserAction();
1784 } 1795 }
1785 } 1796 }
1786 1797
1787 } // namespace views 1798 } // namespace views
OLDNEW
« ui/gfx/render_text.cc ('K') | « ui/views/controls/textfield/textfield.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698